【linux】容器

news2024/11/22 23:46:46

一、虚拟化分类

  • 虚拟化资源提供者

    • 硬件平台虚拟化
    • 操作系统虚拟化
  • 虚拟化实现方式

    • Type I 半虚拟化
    • Type II 硬件辅助全虚拟化
    • Type III
      • 软件全虚拟化
      • 操作系统虚拟化
  • 回顾硬件平台虚拟化与操作系统虚拟化区别

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

  • 主机虚拟化与容器虚拟化的优缺点
    • 主机虚拟化
      • 应用程序运行环境强隔离
      • 虚拟机操作系统与底层操作系统无关化
      • 虚拟机内部操作不会影响到物理机
      • 拥有操作系统会占用部署资源及存储
      • 网络传输效率低
      • 当应用程序需要调用硬件响应用户访问时间延迟大
    • 容器虚拟化
      • 可以实现应用程序的隔离
      • 直接使用物理机的操作系统可以快速响应用户请求
      • 不占用部署时间
      • 占用少量磁盘空间
      • 缺点:学习成本增加、操作控制麻烦、网络控制与主机虚拟化有所区别、服务治理。

二、云平台的技术实现

在这里插入图片描述

  • IaaS 虚拟机
    • 阿里云 ECS
    • OpenStack VM实例
  • PaaS 容器(CaaS)
    • LXC
    • Docker
    • OpenShift
    • Rancher
  • SaaS 应用程序
    • 互联网中应用都是

三、容器所涉及内核技术

  • NameSpce

在这里插入图片描述
UTS:每一个NameSpace都拥有独立的主机或域名,可以把每个NameSpace认为一个独立主机。

IPC:每个容器依旧使用linux内核中进程交互的方法,实现进程间通信

Mount:每个容器的文件系统是独立的

Net:每个容器的网络是隔离

User:每个容器的用户和组ID是隔离,每个容器都拥有root用户

PID:每个容器都拥有独立的进程树,由容器是物理机中的一个进程,所以容器中的进程是物理机的线程

总结

容器使用的命名空间有哪些?

应用程序运行环境隔离的空间,就是一个容器,每一个容器都将拥有UTS,IPC,Mount,Net,User,PID。

  • CGroups
    • 控制组

    • 作用:用于实现容器的资源隔离

    • 可对进程做资源隔离

    • 9大子系统

      • 把资源定义为子系统,可以通过子系统对资源进行限制
      • CPU 可以让进程使用CPU的比例
      • memory 限制内存使用,例如50Mi,150Mi
      • blkio 限制块设备的IO
      • cpuacct 生成Cgroup使用CPU的资源报告
      • cpuset 用于多CPU执行Cgroup时,对进程进行CPU分组
      • devices 允许或拒绝设备的访问
      • freezer 暂停或恢复Cgroup运行
      • net_cls
      • ns
    • 应用案例

      • 通过Cgroup限制进程对CPU的使用
        • 步骤
          • 部署Cgroup
[root@bogon ~]# yum -y install libcgroup*

[root@bogon ~]# systemctl status cgconfig
● cgconfig.service - Control Group configuration service
Loaded: loaded (/usr/lib/systemd/system/cgconfig.service;
disabled; vendor preset: disabled)
Active: inactive (dead)

[root@bogon ~]# systemctl enable cgconfig
Created symlink from
/etc/systemd/system/sysinit.target.wants/cgconfig.service to
/usr/lib/systemd/system/cgconfig.service.

[root@bogon ~]# systemctl start cgconfig

[root@bogon ~]# systemctl status cgconfig
● cgconfig.service - Control Group configuration service
Loaded: loaded (/usr/lib/systemd/system/cgconfig.service; enabled;
vendor preset: disabled)
Active: active (exited) since 四 2019-04-25 16:30:03 CST; 7s ago
Process: 17061 ExecStart=/usr/sbin/cgconfigparser -l
/etc/cgconfig.conf -L /etc/cgconfig.d -s 1664 (code=exited,
status=0/SUCCESS)
Main PID: 17061 (code=exited, status=0/SUCCESS)
4月 25 16:30:03 bogon systemd[1]: Starting Control Group
configuration ser.....
4月 25 16:30:03 bogon systemd[1]: Started Control Group configuration
service.
Hint: Some lines were ellipsized, use -l to show in full.
  • Cgroup限制对CPU使用的步骤

    • 第一步:创建Cgroup组
    • 第二步:把进程添加到Cgroup
  • 案例

#使用cpu子系统创建2个cgroup
[root@bogon ~]# vim /etc/cgconfig.conf
group lesscpu {
      cpu {
           cpu.shares=200;
}
}

group morecpu {
       cpu {
          cpu.shares=800;
}
}
[root@bogon ~]# systemctl restart cgconfig
[root@bogon ~]# cgexec -g cpu:lesscpu md5sum /dev/zero
#终端1
[root@bogon ~]# cgexec -g cpu:morecpu sha1sum /dev/zero
#终端2
[root@bogon ~]# top

在这里插入图片描述
案例2:限制内存使用

  • 错误内存限制
[root@bogon ~]# vim /etc/cgconfig.conf
group lessmem {
        memory {
           memory.limit_in_bytes=268435465;
}
}

[root@bogon ~]# systemctl restart cgconfig
[root@bogon ~]# mkdir /mnt/mem_test

[root@bogon ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.5G 16G 9% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 2.0G 8.7M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda1 1014M 163M 852M 17% /boot
tmpfs 336M 0 336M 0% /run/user/0

[root@bogon ~]#
[root@bogon ~]# mount -t tmpfs /dev/shm /mnt/mem_test

[root@bogon ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.5G 16G 9% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 2.0G 8.7M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda1 1014M 163M 852M 17% /boot
tmpfs 336M 0 336M 0% /run/user/0
/dev/shm 952M 0 952M 0% /mnt/mem_test
[root@bogon ~]#

[root@bogon ~]# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file1 bs=1M
count=200
记录了200+0 的读入
记录了200+0 的写出
209715200字节(210 MB)已复制,0.100733 秒,2.1 GB/秒
[root@bogon ~]# ls /mnt/mem_test/
file1

[root@bogon ~]# rm -rf /mnt/mem_test/file1
[root@bogon ~]# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file1 bs=1M
count=500
记录了500+0 的读入
记录了500+0 的写出
524288000字节(524 MB)已复制,0.353956 秒,1.5 GB/秒
  • 正确的内存限制
[root@bogon ~]# vim /etc/cgconfig.conf

group lessmem {
        memory {
             memory.limit_in_bytes=268435465;
             memory.memsw.limit_in_bytes=268435465;
}
}

[root@bogon ~]# systemctl restart cgconfig
[root@bogon ~]# mount -t tmpfs /dev/shm /mnt/mem_test

[root@bogon ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.5G 16G 9% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 2.0G 8.7M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda1 1014M 163M 852M 17% /boot
tmpfs 336M 0 336M 0% /run/user/0
/dev/shm 952M 0 952M 0% /mnt/mem_test

[root@bogon ~]# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file1 bs=1M
count=200
记录了200+0 的读入
记录了200+0 的写出
209715200字节(210 MB)已复制,0.105744 秒,2.0 GB/秒

[root@bogon ~]# rm -rf /mnt/mem_test/file1
[root@bogon ~]# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file1 bs=1M
count=500
已杀死
  • 扩展
    • 主机虚拟化实现资源隔离的方式
      • 使用Hypervisor中的VMM实现资源隔离
    • PAM
      • 用户认证
      • 资源限制
        • ulimit
        • 仅对用户做资源限制

四、容器管理工具介绍

  • LXC

    • 2008
    • 是第一套完整的容器管理解决方案
    • 不需要任何补丁直接运行在linux内核之上管理容器
    • 创建容器慢,不方便移置
  • Docker

    • 2013
    • dotcloud
    • 是在LXC基础上发展起来的
    • 拥有一套容器管理生态系统
    • 生态系统包含:容器镜像、注册表、RESTFul API及命令行操作界面
    • 属于容器管理系统
  • Docker版本介绍

    • 2017之前版本
      • 1.7 ,1.8,1.9,1.10,1.11,1.12,1.13
    • 2017年3月1日后
      • 把docker做商业开源
        • docker-ce
        • docker-ee
      • 17-03-ce
      • 17-06-ce
      • 18-03-ce
      • 18-06-ce
      • 18-09-ce

五、容器管理工具Docker安装

5.1 部署docker

用于管理容器

5.2 YUM源

5.2.1 官方网址

www.docker.com

5.2.2 docker所使用开发语言

golang

5.2.3 YUM获取

在这里插入图片描述

  • 卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
  • 安装yum-utils获取yum-config-manager
[root@bogon ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

通过yum-config-manager获取docker-ce.repo

[root@bogon ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

[root@bogon ~]# ls /etc/yum.repos.d/
CentOS-Base.repo CentOS-Media.repo epel.repo
CentOS-CR.repo CentOS-Sources.repo epel-testing.repo
CentOS-Debuginfo.repo CentOS-Vault.repo
CentOS-fasttrack.repo docker-ce.repo

5.3 安装docker-ce

[root@bogon ~]# yum repolist
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.huaweicloud.com
* epel: fedora.cs.nctu.edu.tw
* extras: mirrors.163.com
* updates: mirrors.neusoft.edu.cn
docker-ce-stable | 3.5 kB 00:00
(1/2): docker-ce-stable/x86_64/primary_db | 27 kB 00:01
(2/2): docker-ce-stable/x86_64/updateinfo | 55 B 00:01
源标识 源名称 状态
base/7/x86_64 CentOS-7 - Base 10,019
docker-ce-stable/x86_64 Docker CE Stable - x86_64 41
*epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,082
extras/7/x86_64 CentOS-7 - Extras 386
updates/7/x86_64 CentOS-7 - Updates 1,580
repolist: 25,108

[root@bogon ~]# yum list | grep docker-ce
containerd.io.x86_64 1.2.5-3.1.el7 docker-c -
stable
docker-ce.x86_64 3:18.09.5-3.el7 docker-c -
stable
docker-ce-cli.x86_64 1:18.09.5-3.el7 docker-c -
stable
docker-ce-selinux.noarch 17.03.3.ce-1.el7 docker-c -
stable
[root@bogon ~]# yum -y install docker-ce

[root@bogon ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to
/usr/lib/systemd/system/docker.service.

[root@bogon ~]# systemctl start docker
[root@bogon ~]# docker version
Client:
Version: 18.09.5
API version: 1.39
Go version: go1.10.8
Git commit: e8ff056
Built: Thu Apr 11 04:43:34 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.5
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: e8ff056
Built: Thu Apr 11 04:13:40 2019
OS/Arch: linux/amd64
Experimental: false
[root@bogon ~]# docker version
Client:
Version: 18.09.5
API version: 1.39
Go version: go1.10.8
Git commit: e8ff056
Built: Thu Apr 11 04:43:34 2019
OS/Arch: linux/amd64
Experimental: false
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker
daemon running?
#如果出现如上提示,请启动docker服务。

六、使用docker管理容器

6.1 容器&镜像&仓库&daemon&client之间的关系

在这里插入图片描述

6.2 启动容器

验证是否有镜像在本地

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE

本地没有镜像,需要去search镜像
仓库:dockerhub

[root@bogon ~]# docker search centos
NAME DESCRIPTION
STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5315
[OK]

本地没有镜像,需要下载镜像到本地

[root@bogon ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest: sha256:8d487d68857f5bc9595793279b33d082b03713341ddec91054382641d14db861
Status: Downloaded newer image for centos:latest

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 5 weeks ago 202MB

运行容器

[root@bogon ~]# docker run -it --name=c1 centos:latest /bin/bash
[root@333dce61a32d /]#

6.3 docker daemon管理

  • 远程管理docker daemon充分条件

    • 可以把 docker client与docker daemon分开部署
    • 可以通过第三方软件管理docker daemon创建的容器
  • 第一步:关闭docker daemon

修改docker配置文件前,请先关闭docker守护进程

[root@localhost ~]#systemctl stop docker
  • 第二步:修改docker daemon配置文件
    如果想使用/etc/docker/daemon.json管理docker daemon,默认情况下,/etc/docker目录中并没有daemon.json文件,添加后会导致docker daemon无法启动,在添加daemon.json文件之前,请先修改如下文件内容:
修改前:
[root@localhost ~]#vim /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H unix:// #删除-H(含)后面所有内容


修改后:
[root@localhost ~]#vim /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
  • 第三步:加载配置文件
    修改完成后,一定要加载此配置文件
[root@localhost ~]# systemctl daemon-reload
  • 第四步:重新开启docker守护进程
[root@localhost ~]# systemctl start docker
  • 第五步:添加配置文件对docker daemon配置
    通过/etc/docker/daemon.json文件对docker守护进程文件进行配置
[root@localhost ~]#cd /etc/docker

[root@localhost docker]#vim daemon.json
{
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}
[root@localhost ~]#ss -anput | grep ":2375"

[root@localhost ~]#ls /var/run
docker.sock

[root@localhost ~]# systemctl restart docker

docker daemon默认侦听使用的是unix格式,侦听文件:UNIX:///run/docker.sock,添加tcp://0.0.0.0:2375
可实现远程管理。

  • 第六步:实例远程连接方法
[root@localhost ~]# docker -H 远程容器主机 version

不要在命令行后面添加端口

6.4 docker 命令行命令介绍

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  app*        Docker App (Docker Inc., v0.9.1-beta3)
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.9.1-docker)
  compose*    Docker Compose (Docker Inc., v2.12.2)
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  scan*       Docker Scan (Docker Inc., v0.21.0)
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

6.5 docker命令行实现容器管理

6.5.1 容器镜像获取

6.5.1.1 容器镜像分类

  • 系统镜像
  • 应用镜像

6.5.1.2 搜索镜像(dockerhub)

普通命令

[root@bogon ~]# docker search centos

管理类命令

1

6.5.1.3 获取镜像(pull)

普通命令

[root@bogon ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:8d487d68857f5bc9595793279b33d082b03713341ddec91054382641d14db861
Status: Image is up to date for centos:latest

管理命令

[root@bogon ~]# docker image pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:8d487d68857f5bc9595793279b33d082b03713341ddec91054382641d14db861
Status: Image is up to date for centos:latest

6.5.2 容器镜像传输

  • 为了方便使用容器镜像启动多服务

    • 6.5.2.1 如何获取本地容器镜像打包
[root@bogon ~]# docker save --help
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
-o, --output string Write to a file, instead of STDOUT

#以下为镜像打包
[root@bogon ~]# docker save -o centos.tar centos:latest
[root@bogon ~]# ls
centos.tar

6.5.2.2 传输

[root@bogon ~]# scp centos.tar 192.168.145.251:/root
The authenticity of host '192.168.145.251 (192.168.145.251)' can't be established.
ECDSA key fingerprint is SHA256:Fh82qGEdFfkS+Zpy+fX1B7aEUCwHwYYcNwYtbH7hmoo.
ECDSA key fingerprint is MD5:fd:56:b3:45:56:17:77:47:8c:79:b9:0f:9f:17:27:9c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.145.251' (ECDSA) to the list of known hosts.
root@192.168.145.251's password:
centos.tar 100% 200MB
99.9MB/s 00:02

6.5.2.3 导入到本地目录

Usage:  docker load [OPTIONS]

Load an image from a tar archive or STDIN

Options:
  -i, --input string   Read from tar archive file, instead of STDIN
  -q, --quiet          Suppress the load output

[root@bogon ~]# docker load -i centos.tar
d69483a6face: Loading layer 209.5MB/209.5MB
Loaded image: centos:latest

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 6 weeks ago 202MB

6.5.3 启动容器

6.5.3.1 启动一个运行bash命令的容器

[root@bogon ~]# docker run -it --name=c1 centos:latest /bin/bash

[root@bogon ~]# docker container run -it --name=c2 centos:latest /bin/bash

6.5.3.2 启动一个运行httpd服务的容器

启动一个容器

 [root@bogon ~]# docker run -it --name=c1 centos:latest /bin/bash

在容器中安装httpd

[root@b8f1c4b45e37 /]# yum -y install httpd
[root@b8f1c4b45e37 /]# /usr/sbin/httpd -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name,
using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
[root@b8f1c4b45e37 /]# curl http://localhost
container webpage

6.5.4 基于容器生成文件导入为容器镜像

[root@bogon ~]# docker export --help
Usage: docker export [OPTIONS] CONTAINER
Export a container's filesystem as a tar archive

Options:
-o, --output string Write to a file, instead of STDOUT
[root@bogon ~]# docker export -o centos-httpd.tar c3
[root@bogon ~]# ls
centos-httpd.tar

[root@bogon ~]# docker import --help
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
Options:
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Set commit message for imported image

[root@bogon ~]# docker import -m httpd centos-httpd.tar centos-httpd:v1
sha256:da4dfb859952ecc9b0499f43b9be7d712db0e21e699120c9ae78581b15fa6d1e

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-httpd v1 da4dfb859952 26 seconds ago 295MB

[root@bogon ~]# docker history centos-httpd:v1
IMAGE CREATED CREATED BY SIZE
COMMENT
da4dfb859952 About a minute ago 295MB httpd # 这就是注释

[root@bogon ~]# docker run -it --name c4 centos-httpd:v1 /bin/bash
[root@b175010389d2 /]# httpd -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name,
using 172.17.0.4. Set the 'ServerName' directive globally to suppress this message
[root@b175010389d2 /]# curl http://localhost
container webpage

6.5.5 查看容器IP地址

[root@bogon ~]# ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group
default
link/ether 02:42:51:3d:45:08 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:51ff:fe3d:4508/64 scope link
valid_lft forever preferred_lft forever  #容器默认连接的网桥

方法一:

[root@bogon ~]# docker run -it --name c2 centos /bin/bash

[root@d56146c41f3a /]# ip a s
bash: ip: command not found #没有此命令,需要安装

[root@d56146c41f3a /]# yum -y install iproute

[root@d56146c41f3a /]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen
1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever#由docker0网桥分配

方法二:

[root@bogon ~]# docker inspect c2   #查看容器详细信息

方法三:

[root@bogon ~]# docker exec c2 ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen
1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever   #在容器外执行容器内命令

6.5.6 停止运行中的容器

[root@bogon ~]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
d56146c41f3a centos "/bin/bash" 12 minutes ago Up 11
minutes c2

[root@bogon ~]# docker stop d #停止一个正在运行的容器,d是容器ID简写,也可以写容器名称,但是ID要
能够唯一识别
d
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES

[root@bogon ~]# docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
d56146c41f3a centos "/bin/bash" 13 minutes ago Exited
(137) 14 seconds ago c2
9e44437412ab centos:latest "/bin/bash" 2 hours ago Exited
(0) 18 minutes ago c1

#关闭多个正在运行的容器
[root@bogon ~]# docker start c1 c2
c1
c2

[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
d56146c41f3a centos "/bin/bash" 16 minutes ago Up 7
seconds c2
9e44437412ab centos:latest "/bin/bash" 2 hours ago Up 7
seconds c1

[root@bogon ~]# docker stop c1 c2

6.5.7 开启已停止的容器

启动

[root@bogon ~]# docker start c1
c1

进入

[root@bogon ~]# docker attach --help
Usage: docker attach [OPTIONS] CONTAINER
Attach local standard input, output, and error streams to a running container
Options:
--detach-keys string Override the key sequence for detaching a container
--no-stdin Do not attach STDIN
--sig-proxy Proxy all received signals to the process (default true)

[root@bogon ~]# docker attach c1

[root@9e44437412ab /]#

6.5.8 删除已停止容器

[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
9e44437412ab centos:latest "/bin/bash" 2 hours ago Up 2
seconds c1

[root@bogon ~]# docker rm c1
Error response from daemon: You cannot remove a running container
9e44437412abc3b76263855df597b523ee8a4ad617f9529d2c1afd7eb551f2ec. Stop the container
before attempting removal or force remove

[root@bogon ~]# docker stop c1
c1

[root@bogon ~]# docker rm c1
c1

[root@bogon ~]# docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
d56146c41f3a centos "/bin/bash" 23 minutes ago Exited
(137) 6 minutes ago c2

6.5.9 容器端口映射

[root@bogon ~]# docker run -it -p 80:80 --name c101 centos:latest /bin/bash

[root@991dbf27676e /]# yum -y install httpd iproute

[root@991dbf27676e /]# echo "197-0.2-webpage" >> /var/www/html/index.html

[root@991dbf27676e /]# httpd -k start

[root@991dbf27676e /]# curl http://172.17.0.2
197-0.2-webpage

#在容器主机上访问容器IP
[root@bogon ~]# curl http://172.17.0.2
197-0.2-webpage

#在容器主机上访问容器主机的80端口
[root@bogon ~]# curl http://192.168.122.197
197-0.2-webpage

#在192.168.122.185主机访问192.168.122.197,最终成功访问192.168.122.197容器主机中的容器所提供的http服务。
[root@bogon ~]# curl http://192.168.122.197
197-0.2-webpage

#192.168.122.197容器主机上查看容器的状态
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
991dbf27676e centos:latest "/bin/bash" 8 minutes ago Up 8
minutes 0.0.0.0:80->80/tcp c101
#请大家思考:如果容器主机上同时运行多个http服务的容器,请问端口怎么映射?
#TCP 1-65535
#UDP 1-65535
#端口是稀缺资源
#如果仅定义了容器的端口,那么容器主机会随机添加映射端口到容器80端口,随机端口大于或等于32768
[root@bogon ~]# docker run -it -p 80 --name c101 centos:latest /bin/bash
[root@2aae7d6217ff /]# [root@bogon ~]#
[root@bogon ~]#
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
2aae7d6217ff centos:latest "/bin/bash" 6 seconds ago Up 5
seconds 0.0.0.0:32768->80/tcp c101

#使用容器主机的某一IP地址上的端口做随机映射
[root@bogon ~]# docker run -it -p 192.168.122.197::80 --name c101 centos /bin/bash
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
b33b384c0b8a centos "/bin/bash" 7 seconds ago Up 7
seconds 192.168.122.197:32768->80/tcp c101

6.5.10 容器使用Docker Host存储数据

第一步:在Docker Host创建用于存储目录

[root@bogon ~]# mkdir /opt/cvolume

第二步:运行容器并挂载上述目录

[root@bogon ~]# docker run -it -v /opt/cvloume:/data --name c103 centos:latest
/bin/bash

[root@fcfb623370b6 /]# ls /
anaconda-post.log data(#新创建的目录) etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var

案例:运行在容器中的http服务,使用docker host的/web目录中的网页文件,并能够在doker host上进行修改,修改后立即生效。

第一步:创建/web并添加网页文件

[root@bogon ~]# mkdir /web
[root@bogon ~]# echo "web" >> /web/index.html

第二步:启动容器对/web目录进行挂载

[root@bogon ~]# docker run -it -p 8080:80/tcp -v /web:/var/www/html --name c200
centos:latest /bin/bash

[root@d96b5914ac99 /]# ls /var/www/html
index.html

第三步:访问http(在192.168.122.185)

[root@bogon ~]# curl http://192.168.122.197:8080
web

额外配置案例:同步容器与docker host时间

[root@bogon ~]# docker run -it -v /etc/localtime:/etc/localtime centos:latest /bin/bash
[root@af986201c67e /]# date
Fri Apr 26 16:20:18 CST 2019

6.5.11 在容器外执行容器内命令

[root@bogon ~]# docker exec c101 ls /
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

6.5.12 容器间互联(–link)

第一步:创建被依赖容器

[root@bogon ~]# docker run -it --name c202 centos:latest /bin/bash

第二步:创建依赖于源容器的容器

[root@bogon ~]# docker run --link c202:mysqldb -it --name c203 centos:latest /bin/bash

[root@759f83e2ab39 /]# ping mysqldb
PING mysqldb (172.17.0.6) 56(84) bytes of data.
64 bytes from mysqldb (172.17.0.6): icmp_seq=1 ttl=64 time=0.158 ms
64 bytes from mysqldb (172.17.0.6): icmp_seq=2 ttl=64 time=0.110 ms
^C
--- mysqldb ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.110/0.134/0.158/0.024 ms

[root@759f83e2ab39 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.6 mysqldb e23172d55390 c202
172.17.0.7 759f83e2ab39

第三步:验证

关闭容器

[root@bogon ~]# docker stop c202 c203

添加一个新的容器,用于抢占c202的IP

[root@bogon ~]# docker run -it centos /bin/bash

启动c202及c203

[root@bogon ~]# docker start c202
c202
[root@bogon ~]# docker start c203
c203
[root@bogon ~]# docker exec c203 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.7 mysqldb e23172d55390 c202
172.17.0.8 759f83e2ab39

七、docker容器镜像

容器与镜像之间的关系:

  • docker client 向docker daemon发起创建容器的请求
  • docker daemon查找有无客户端需要的镜像
  • 如无,则到容器的镜像仓库中下载需要的镜像
  • 拿到容器镜像后,启动容器

7.1 容器镜像介绍

Docker 镜像就是一组只读的目录,或者叫只读的 Docker 容器模板,镜像中含有一个Docker 容器运行所需要的文件系统,所以我们说Docker 镜像是启动一个Docker 容器的基础。

可以将Docker 镜像看成是Docker 容器的静态时,也可将Docker 容器看成是Docker镜像的运行时。

从Docker 的官方文档来看,Docker 容器的定义和 Docker 镜像的定义几乎是相同,Docker 容器和Docker 镜像的区别主要在于docker 容器多出了一个可写层。
在这里插入图片描述
容器中的进程就运行在这个可写层,这个可写层有两个状态,即运行态和退出态。当我们docker run 运行容器后,docker 容器就进入了运行态,当我们停止正在运行中的容器时,docker 容器就进入了退出态。

我们将容器从运行态转为退出态时,期间发生的变更都会写入到容器的文件系统中(需要注意的是,此处不是写入到了docker 镜像中)。

联合文件系统(UnionFS)是一种轻量级的高性能分层文件系统,它支持将文件系统中的修改信息作为一次提交,并层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,应用看到的是挂载的最终结果。

联合文件系统是实现Docker镜像的技术基础。Docker镜像可以通过分层来进行继承。例如,用户基于基础镜像(用来生成其他镜像的基础,往往没有父镜像)来制作各种不同的应用镜像。这些镜像共享同一个基础镜像层,提高了存储效率。此外,当用户改变了一个Docker镜像(比如升级程序到新的版本),则会创建一个新的层(layer)。因此,用户不用替换整个原镜像或者重新建立,只需要添加新层即可。用户分发镜像的时候,也只需要分发被改动的新层内容(增量部分)。这让Docker的镜像管理变得十分轻量级和快速。

在这里插入图片描述

7.1.1 制作基础镜像

7.1.1.1 安装一个最小化的操作系统主机
7.1.1.2 打包操作系统的根目录
  • 排除/proc及/sys
[root@bogon ~]# tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7u6.tar /
7.1.1.3 把获取的根打包文件导入Docker Host中
[root@bogon ~]# docker import centos7u6.tar centos7u6:latest

[root@bogon ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6 latest 9223c5786c4c 15 seconds ago 1.5GB
7.1.1.4 使用基础镜像启动容器
[root@bogon ~]# docker run -it --name c1000 centos7u6:latest /bin/bash

[root@f56add98265c /]# ls /proc
1 cpuinfo fs kmsg mounts slabinfo tty
22 crypto interrupts kpagecount mtrr softirqs uptime
acpi devices iomem kpageflags net stat version
asound diskstats ioports loadavg pagetypeinfo swaps
vmallocinfo
buddyinfo dma irq locks partitions sys vmstat
bus driver kallsyms mdstat sched_debug sysrq-trigger zoneinfo
cgroups execdomains kcore meminfo schedstat sysvipc
cmdline fb keys misc scsi timer_list
consoles filesystems key-users modules self timer_stats

[root@f56add98265c /]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen
1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42:ac:11:00:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.9/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

7.1.2 应用镜像制作

  • 指应用程序运行的环境
7.1.2.1 使用commit提交镜像

在基础镜像运行的容器中安装应用,此例使用httpd

[root@f56add98265c /]# yum -y install httpd

使用commit命令对正在运行的容器提交为一个应用镜像

[root@bogon ~]# docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes

Options:
-a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)

[root@bogon ~]# docker commit c1000 centos7u6-httpd:v1
sha256:7bc399ab72aa3335e383e58d709770fa5c3bfeee66cccf7976776e22fe5fedc7

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6-httpd v1 7bc399ab72aa 5 seconds ago 1.67GB

使用应用镜像

[root@bogon ~]# docker run -it centos7u6-httpd:v1 /bin/bash

[root@1abdebd392db /]# echo "ttt" >> /var/www/html/index.html

[root@1abdebd392db /]# httpd -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name,
using 172.17.0.10. Set the 'ServerName' directive globally to suppress this message

[root@1abdebd392db /]# curl http://localhost
ttt
7.1.2.2 使用Dockerfile创建应用镜像

7.1.2.2.1 使用docker build命令

7.1.2.2.2 基于Dockerfile

7.1.2.2.3 Dockfile原理
在Dockerfile定义所要执行的命令,使用docker build创建镜像,过程中会按照Dockerfile所定义的内容打开临时性容器(使用docker commit进行提交),把Dockerfile文件中的命令全部执行完成,就得到了一个容器应用镜像。

  • 执行命令越多,最终得到的容器应用镜像越大,所以要做优化

7.1.2.2.4 Dockerfile关键字

  • FROM(指定基础image)
  • MAINTAINER(用来指定镜像创建者信息)
  • RUN (运行命令)
  • CMD(设置container启动时执行的操作)
    • 如果容器镜像中有此命令,启动容器时,不要手动让容器执行其它命令
  • ENTRYPOINT(设置container启动时执行的操作)
  • USER(设置container容器的用户)
  • EXPOSE(指定容器需要映射到宿主机器的端口)
  • ENV(用于设置环境变量)
  • ADD(从src复制文件到container的dest路径)
  • VOLUME(指定挂载点)
  • WORKDIR(切换目录)

7.1.2.2.5 Dockerfile应用案例

目的:通过Dockerfile创建一个可以在启动容器时就直接启动httpd应用的镜像

步骤:

  • 创建一个目录,用于存储Dockerfile所使用的文件
  • 在此目录中创建Dockerfile文件及制作镜像所使用到的文件
  • 在此此目录中使用docker build创建镜像(读取Dockerfile文件)
  • 使用创建的镜像启动容器

思考:

  1. 基础镜像是谁?centos7u6
  2. 安装httpd
  3. yum -y install httpd
  4. 安装完成后如何启动httpd? 编写一个把httpd启动的脚本文件
  5. 把httpd放在前端执行还是后端执行?前端
  6. 暴露端口?tcp80
  7. 添加一个测试文件,用于验证httpd是否可用?
    过程:

创建目录

[root@bogon ~]# mkdir test

进入目录并创建用于启动httpd的脚本文件

[root@bogon ~]# cd test
[root@bogon test]# cat run-httpd.sh
#!/bin/bash
rm -rf /run/httpd/*
exec /sbin/httpd -D FOREGROUND

创建用于测试httpd是否可用的index.html

[root@bogon test]# cat index.html
It's work!!!

创建Dockerfile

[root@bogon test]# cat Dockerfile
FROM centos7u6:latest
MAINTAINER "smartdocker@smartdocker@126.com"
RUN yum clean all
RUN rpm --rebuilddb && yum -y install httpd
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh
ADD index.html /var/www/html/
EXPOSE 80
WORKDIR /
CMD ["/bin/bash","/run-httpd.sh"]

使用docker build创建镜像,注意命令最后有一个点,点表示当前目录

[root@bogon test]# docker build -t centos7u6-base-httpd:v1 .

使用上述创建的应用容器启动容器

[root@bogon test]# docker run -d centos7u6-base-httpd:v1

验证容器及httpd是否可用

[root@bogon test]# docker inspect 31d #查看容器IP地址
[root@bogon test]# curl http://172.17.0.11
It's work!!!

替代原网站内容案例

[root@bogon test]# mkdir /wwwroot
[root@bogon test]# echo "wwwroot" >> /wwwroot/index.html
[root@bogon test]# docker run -d -v /wwwroot:/var/www/html centos7u6-base-httpd:v1
415e82ad0041aa18bcb92bc8edbdf9bd758915a8345c71266f51937de3a20a26
[root@bogon test]# docker inspect 415
[root@bogon test]# curl http://172.17.0.12
wwwroot

如果遇到Rpmdb错误,可以考虑安装:yum-plugin-ovl软件包。

案例:把nginx应用容器化
要求:
1、通过基础镜像做nginx应用镜像
2、使用nginx应用镜像启动容器时,nginx要求启动
3、验证nginx服务是否启动

步骤:
1、使用哪一个基础 centos:latest
2、需要使用epel YUM源
3、安装nginx
4、修改nginx配置文件,主要用于关闭daemon后台运行
5、验证使用的测试页面

创建目录

[root@localhost ~]# mkdir nginxtest
[root@localhost ~]# cd nginxtest/
[root@localhost nginxtest]#

创建测试文件

[root@localhost nginxtest]# echo 'nginx s running!!!' >> index.html
[root@localhost nginxtest]# ls
index.html

创建Dockerfile

[root@localhost nginxtest]# cat Dockerfile
FROM centos:latest
MAINTAINER "smartaiops<smartaiops@126.com>"
RUN yum clean all && yum -y install yum-plugin-ovl && yum -y install epel-release
RUN yum -y install nginx
ADD index.html /usr/share/nginx/html/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf #取消nginx以daemon身份运行
EXPOSE 80
CMD /usr/sbin/nginx

使用docker build创建nginx应用镜像

 [root@localhost nginxtest]# docker build -t centos-nginx:v1 .

启动容器验证nginx服务是否自动开启

[root@localhost nginxtest]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
centos-nginx v1 cf23c20ff2cd 20 seconds ago
466MB

[root@localhost nginxtest]# docker run -d centos-nginx:v1
5b1d6dae77d24d9c8dc136a5bf971ebe296e1463838bda46e586d07d6f572f6d

[root@localhost nginxtest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
5b1d6dae77d2 centos-nginx:v1 "/bin/sh -c /usr/sbi…" 9 seconds ago
Up 8 seconds 80/tcp upbeat_khayyam

[root@localhost nginxtest]# docker inspect 5b1d

[root@localhost nginxtest]# curl http://172.17.0.3
nginx s running!!!

7.2 容器镜像在docker host存储位置

在这里插入图片描述
从图中可以看出除了最上面的一层为读写层之外,下面的其他的层都是只读的镜像层,并且除了最下面的一层外,其他的层都有会有一个指针指向自己下面的一层镜像。

虽然统一文件系统(union file system)技术将不同的镜像层整合成一个统一的文件系统,为构成一个完整容器镜像的层提供了一个统一的视角,隐藏了多个层的复杂性,对用户来说只存在一个文件系统,但图中的这些层并不是不能看到的,如果需要查看的话可以进入运行Docker的机器上进行查看,从这些层中可以看到Docker 内部实现的一些细节。

Docker 的容器镜像和容器本身的数据都存放在服务器的 /var/lib/docker/ 这个路径下。不过不同的linux发行版存储方式上有差别,比如,在ubuntu发行版上存储方式为AUFS,CentOS发行版上的存储方式为Overlay或Overlay2。

centos系统docker默认使用存储驱动是devicemapper,而这种存储驱动有两种模式loop-lvm和direct-lvm,
不巧默认又使用了比较低效的loop-lvm。

OverlayFS是一个类似于AUFS 的现代联合文件系统,更快实现简单。
OverlayFS是内核提供的文件系统,overlay和overlay2是docker的存储驱动

7.2.1 Overlay及Overlay2原理

OverlayFS将单个Linux主机上的两个目录合并成一个目录。这些目录被称为层,统一过程被称为联合挂载。OverlayFS底层目录称为lowerdir, 高层目录称为upperdir。合并统一视图称为merged。当需要修改一个文件时,使用CoW将文件从只读的Lower复制到可写的Upper进行修改,结果也保存在Upper层。在Docker中,底下的只读层就是image,可写层就是Container。

overlay2是overlay的改进版,只支持4.0以上内核添加了Multiple lower layers in overlayfs的特性,所以overlay2可以直接造成muitiple lower layers不用像overlay一样要通过硬链接的方式(最大128层) centos的话支持3.10.0-514及以上内核版本也有此特性,所以消耗更少的inode

本质区别是镜像层之间共享数据的方法不同

  • overlay共享数据方式是通过硬连接,只挂载一层,其他层通过最高层通过硬连接形式共享(增加了磁盘inode的负担)
  • 而overlay2是通过每层的 lower文件

在这里插入图片描述

如果upperdir和lowerdir有同名文件时会用upperdir的文件

查看docker默认使用的存储驱动方法

[root@bogon overlay2]# docker info
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 1
Server Version: 18.09.5
Storage Driver: overlay2 #注意此处

7.2.2 docker运行前

/var/lib/docker/overlay2 路径下的信息在不同的阶段会有变化,了解这几个阶段中新增的数据以及容器与镜像的存储结构的变化非常有利于我们对Docker容器以及Docker镜像的理解。

Docker运行前、Docker运行后、下载镜像后、运行容器后四个阶段中Docker 存储的变化

7.2.2.1 运行前

没有启动docker daemon之间不会在/var/lib/目录中添加docker目录

7.2.2.2 启动后
[root@bogon ~]# systemctl start docker
[root@bogon ~]# tree /var/lib/docker
/var/lib/docker
├── builder
│ └── fscache.db
├── buildkit
│ ├── cache.db
│ ├── content
│ │ └── ingest
│ ├── executor
│ ├── metadata.db
│ └── snapshots.db
├── containers
├── image
│ └── overlay2
│ ├── distribution
│ ├── imagedb
│ │ ├── content
│ │ │ └── sha256
│ │ └── metadata
│ │ └── sha256
│ ├── layerdb
│ └── repositories.json
├── network
│ └── files
│ └── local-kv.db
├── overlay2 #下载镜像后,存储在此目录中
│ ├── backingFsBlockDev
│ └── l
├── plugins
│ ├── storage
│ │ └── blobs
│ │ └── tmp
│ └── tmp
├── runtimes
├── swarm
├── tmp
├── trust
└── volumes
└── metadata.db
29 directories, 8 files
7.2.2.3 下载镜像后
[root@bogon overlay2]# pwd
/var/lib/docker/overlay2

[root@bogon overlay2]# ls
2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d backingFsBlockDev l

[root@bogon overlay2]# ls
2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d/
diff link

[root@bogon overlay2]# ls 2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d/diff/
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr

centos镜像只有一层

[root@bogon overlay2]# pwd
/var/lib/docker/overlay2

[root@bogon overlay2]# ls 2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d backingFsBlockDev l
[root@bogon overlay2]# ll l
总用量 0
lrwxrwxrwx 1 root root 72 4月 26 12:58 MBRXMBFE2MYZYMO5RZLRLTMRGJ ->
../2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d/diff

l目录中包含了很多多软链接,使用短名称指向了其他层,短名称用于避免mount参数时达到页面大小的限制

7.2.2.4 运行容器后

Overlay2容器结构

#运行容器前
[root@bogon overlay2]# ls
2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d backingFsBlockDev l

#运行容器后
[root@bogon overlay2]# ls
00bd7dcc4c91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cda0
backingFsBlockDev
00bd7dcc4c91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cda0-init l
2d297a77c653f510dce69815627fdb485462b1b2fc9e0078a9ecc5ca2d222c8d

[root@bogon overlay2]# ll
00bd7dcc4c91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cda0
总用量 8
drwxr-xr-x 2 root root 6 4月 26 13:15 diff
-rw-r--r-- 1 root root 26 4月 26 13:15 link
-rw-r--r-- 1 root root 57 4月 26 13:15 lower
drwxr-xr-x 1 root root 6 4月 26 13:15 merged
drwx------ 3 root root 18 4月 26 13:15 work
  • 启动一个容器,也是载/var/lib/docker/overlay2目录下生成一层容器层,目录包括diff,link,lower,
    merged,work。
  • diff记录每一层自己内容的数据;link记录该层链接目录(实际是l目录下到层的链接),比如在容器中创建目录或在diff新增该目录;创建容器时将lower-id指向的镜像层目录以及upper目录联合挂载到merged目录;work用来完成如copy-on_write的操作。

启动容器后,可以在docker host查看mount情况

[root@bogon overlay2]# mount | grep overlay
overlay on
/var/lib/docker/overlay2/00bd7dcc4c91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cd
a0/merged type overlay
(rw,relatime,lowerdir=/var/lib/docker/overlay2/l/4GXMF7JGUPRUBLW5SM4X4FY5R2:/var/lib/do
cker/overlay2/l/MBRXMBFE2MYZYMO5RZLRLTMRGJ,upperdir=/var/lib/docker/overlay2/00bd7dcc4c
91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cda0/diff,workdir=/var/lib/docker/ove
rlay2/00bd7dcc4c91f9a1a1257b8c0683fdd0b6dfe18af26597457e92b4d15c20cda0/work)

7.3 官方镜像仓库介绍

7.3.1 镜像仓库分类

  • 公有仓库
  • 私有仓库

7.3.2 官方镜像仓库

  • 属于公有仓库

  • 网址:hub.docker.com 网站名称: dockerhub

    在这里插入图片描述

  • 注册

    • 邮箱

在这里插入图片描述

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

  • 创建仓库
    • 创建自己的仓库

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

  • 登录仓库
    • web界面登录

在这里插入图片描述

  • linux命令行登录
[root@bogon ~]# docker --help
[root@bogon ~]# docker login hub.docker.com
[root@bogon ~]# 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: smartgodocker
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

上传时需要登录
2、当有私有镜像仓库使用时需要登录

登录

[root@bogon ~]# docker logout
Removing login credentials for https://index.docker.io/v1/

7.4 dockerhub镜像上传、下载

7.4.1 镜像上传

7.4.1.1 给需要上传到公有仓库的容器镜像打标记
[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 6 weeks ago 202MB
[root@bogon ~]# docker tag centos:latest smartgodocker/centos:v1
[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 6 weeks ago
202MB
smartgodocker/centos v1 9f38484d220f 6 weeks ago
202MB
7.4.1.2 把已打标记的容器镜像上传到公有仓库
[root@bogon ~]# 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: smartgodocker
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@bogon ~]# docker push smartgodocker/centos:v1
The push refers to repository [docker.io/smartgodocker/centos]
d69483a6face: Mounted from library/centos
v1: digest: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66
size: 529

在这里插入图片描述

7.4.2 镜像下载

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
centos latest 9f38484d220f 6 weeks ago
202MB
smartgodocker/centos v1 9f38484d220f 6 weeks ago
202MB
您在 /var/spool/mail/root 中有新邮件
[root@bogon ~]# docker logout
Removing login credentials for https://index.docker.io/v1/

[root@bogon ~]# docker pull smartgodocker/centos-nginx:v1
v1: Pulling from smartgodocker/centos-nginx
8ba884070f61: Already exists
b49e39a48ce9: Pull complete
ee8f9e32e5d1: Pull complete
76444f96007d: Pull complete
3a3e79f9d90d: Pull complete
Digest: sha256:b51c09890e5dca970a846012c05123b8eeab9e55a3ea7b94408ae42c718389d9
Status: Downloaded newer image for smartgodocker/centos-nginx:v1
[root@bogon ~]# docker images

7.5 镜像加速器

镜像加速器主要目的在于加快用户下载容器镜像速度

7.5.1 docker中国

7.5.1.1 网址

www.docker-cn.com

7.5.1.2 镜像加速器

在这里插入图片描述

永久配置方法

第一步:修改/usr/lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
#把上述行时行修改,修改如下:
ExecStart=/usr/bin/dockerd

第二步:在/etc/docker/daemon.json

[root@bogon ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

第三步:重启docker daemon

[root@bogon ~]# systemctl daemon-reload
[root@bogon ~]# systemctl restart docker

第四步:验证加速器是否可用

[root@bogon ~]# docker pull ansible/centos7-ansible:latest
latest: Pulling from ansible/centos7-ansible
45a2e645736c: Downloading 29.48MB/70.39MB
1c3acf573616: Downloading 30.1MB/59.73MB
edcb61e55ccc: Download complete
cbae31bad30a: Download complete
aacbdb1e2a62: Download complete
fdeea4fb835c: Downloading 48.93MB/69.68MB

7.5.2 阿里云加速器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改/etc/docker/daemon.json

[root@bogon ~]# cat /etc/docker/daemon.json
{
"registry-mirrors":
["https://s27w6kze.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}

重启服务

 [root@bogon ~]# systemctl restart docker

八、docker本地容器镜像仓库

8.1 作用

  • 在局域内使用
  • 方便与其它系统进行集成
  • 上传下载大镜像时

8.2 使用registry容器镜像实现本地非安全镜像仓库

8.2.1 下载registry容器镜像

[root@bogon ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
c87736221ed0: Pull complete
1cc8e0bb44df: Pull complete
54d33bcb37f5: Pull complete
e8afc091c171: Pull complete
b4541f6d3db6: Pull complete
Digest: sha256:3b00e5438ebd8835bcfa7bf5246445a6b57b9a50473e89c02ecc8e575be3ebb5
Status: Downloaded newer image for registry:latest

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
smartgodocker/centos-nginx v1 cf23c20ff2cd 5 hours ago
466MB
centos latest 9f38484d220f 6 weeks ago
202MB
smartgodocker/centos v1 9f38484d220f 6 weeks ago
202MB
registry latest f32a97de94e1 7 weeks ago
25.8MB

8.2.2 创建用于挂载至registry镜像启动的仓库中,便于容器镜像持久保存

[root@bogon ~]# mkdir /opt/dockerregistry

8.2.3 启动容器获取镜像仓库

[root@bogon ~]# docker run -d -p 5000:5000 --restart=always -v /opt/dockerregistry:/var/lib/registry registry:latest
aa890374e3abdf2aafccd894b2e4e42d633708f06318ea9f954ba2caa52f5b75

[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
aa890374e3ab registry:latest "/entrypoint.sh /etc…" 8 seconds ago Up
7 seconds 0.0.0.0:5000->5000/tcp optimistic_khayyam

8.2.4 验证是否用可

[root@bogon ~]# curl http://192.168.122.33:5000/v2/_catalog
{"repositories":[]}
[root@bogon ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.122.33:5000"],
"registry-mirrors":
["https://s27w6kze.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}

[root@bogon ~]# systemctl restart docker

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
smartgodocker/centos-nginx v1 cf23c20ff2cd 5 hours ago
466MB
centos latest 9f38484d220f 6 weeks ago
202MB
smartgodocker/centos v1 9f38484d220f 6 weeks ago
202MB
registry latest f32a97de94e1 7 weeks ago
25.8MB

[root@bogon ~]# docker tag centos:latest 192.168.122.33:5000/centos:v1

[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
smartgodocker/centos-nginx v1 cf23c20ff2cd 5 hours ago
466MB
centos latest 9f38484d220f 6 weeks ago
202MB
smartgodocker/centos v1 9f38484d220f 6 weeks ago
202MB
192.168.122.33:5000/centos v1 9f38484d220f 6 weeks ago
202MB
registry latest f32a97de94e1 7 weeks ago
25.8MB

[root@bogon ~]# docker push 192.168.122.33:5000/centos:v1
The push refers to repository [192.168.122.33:5000/centos]
d69483a6face: Pushed
v1: digest: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66
size: 529

[root@bogon ~]# ls /opt/dockerregistry/
docker
[root@bogon ~]# ls /opt/dockerregistry/docker/
registry
[root@bogon ~]# ls /opt/dockerregistry/docker/registry/
v2
[root@bogon ~]# ls /opt/dockerregistry/docker/registry/v2/
blobs repositories
[root@bogon ~]# ls /opt/dockerregistry/docker/registry/v2/repositories/
centos
#在其它主机中使用此镜像仓库
#第一步修改:/usr/lib/systemd/system/docker.service
#第二步创建:/etc/docker/daemon.json
#添加内容: "insecure-registries": ["http://192.168.122.33:5000"]
#第三步:重启 [root@bogon ~]# systemctl daemon-reload;systemctl restart docker
#第四步:下载容器镜像
[root@bogon ~]# docker pull 192.168.122.33:5000/centos:v1
v1: Pulling from centos
Digest: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66
Status: Downloaded newer image for 192.168.122.33:5000/centos:v1

8.3 使用registry容器镜像实现本地基于用户名和密码访问的非安全镜像仓库

8.3.1 添加用户

[root@localhost ~]# mkdir /opt/data/auth/
[root@localhost ~]# docker run --entrypoint htpasswd registry:latest -Bbn tom 123 >> /opt/data/auth/htpasswd

8.3.2 启动仓库

[root@localhost ~]#docker run -d -p 5000:5000 --restart=always \
-v /opt/data/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e “REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd” \
-v /opt/data/docker/registry:/var/lib/registry/ registry:latest

8.3.3 登录登出

[root@localhost ~]# docker login 私有仓库所在主机IP:5000
Username: tom
Password: 123
[root@localhost ~]#docker logout 私有仓库所在主机IP:5000

8.4 使用Harbor实现本地通过web进行管理的非安全仓库

8.4.1 认识harbor

  • vmware公司开源
  • 良好的中文界面
  • web管理界面
  • 使用广泛

8.4.2 工具准备

  • 使用docker-compose工具进行启动
  • 准备安装docker-compose有工具-pip
  • pip类似于yum,用于批量安装python模块及解决python模块依赖

pip工具准备

[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install python2-pip
[root@bogon ~]# pip install --upgrade pip

docker-compose工具准备

[root@bogon ~]# pip install docker-compose
#centos7.6 reqeuest=2.21.0

8.4.3 获取harbor

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

8.4.4 解压

[root@bogon ~]# tar xf harbor-offline-installer-v1.7.5.tgz

8.4.5 配置

[root@bogon ~]# ls
123.link 123.txt.link centos7u6.tar harbor-offline-installer-v1.7.5.tgz
123.txt anaconda-ks.cfg harbor

[root@bogon ~]# cd harbor

[root@bogon harbor]# cat harbor.cfg

## Configuration file of Harbor
#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version = 1.7.0
#The IP address or hostname to access admin UI and registry service.
#DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external
clients.
#DO NOT comment out this line, modify the value of "hostname" directly, or the
installation will fail.
hostname = 192.168.122.33 #此为重点

8.4.6 启动

[root@bogon harbor]# ./prepare
Generated and saved secret to file: /data/secretkey
Generated configuration file: ./common/config/nginx/nginx.conf
Generated configuration file: ./common/config/adminserver/env
Generated configuration file: ./common/config/core/env
Generated configuration file: ./common/config/registry/config.yml
Generated configuration file: ./common/config/db/env
Generated configuration file: ./common/config/jobservice/env
Generated configuration file: ./common/config/jobservice/config.yml
Generated configuration file: ./common/config/log/logrotate.conf
Generated configuration file: ./common/config/registryctl/env
Generated configuration file: ./common/config/core/app.conf
Generated certificate, key file: ./common/config/core/private_key.pem, cert file:
./common/config/registry/root.crt
The configuration files are ready, please use docker-compose to start the service.
[root@bogon harbor]# ./install.sh
#安装

8.4.7 访问

在这里插入图片描述

8.4.8 上传镜像到harbor镜像私有仓库

8.4.8.1 在daemon.json中添加此仓库地址
[root@bogon harbor]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.122.33"],
"registry-mirrors":
["https://s27w6kze.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}
[root@bogon harbor]# systemctl restart docker
8.4.8.2 给需要上传的镜像打标记

在这里插入图片描述

[root@bogon harbor]# docker tag smartgodocker/centos-nginx:v1
192.168.122.33/library/centos-nginx:v1

[root@bogon harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
smartgodocker/centos-nginx v1 cf23c20ff2cd 7 hours
ago 466MB
192.168.122.33/library/centos-nginx v1 cf23c20ff2cd 7 hours
ago 466MB
8.4.8.3 上传

登录harbor

[root@bogon harbor]# docker login http://192.168.122.33
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

上传镜像

[root@bogon harbor]# docker push 192.168.122.33/library/centos-nginx:v1
The push refers to repository [192.168.122.33/library/centos-nginx]
e392868b1aec: Pushed
6a7d23d1440a: Pushed
0c580d4106bc: Pushed
8ef5817e55a0: Pushed
d69483a6face: Pushed
v1: digest: sha256:b51c09890e5dca970a846012c05123b8eeab9e55a3ea7b94408ae42c718389d9
size: 1368

验证是否上传成功
在这里插入图片描述

8.4.9 在其它服务器上访问harbor

[root@bogon ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.122.33"]
}

[root@bogon ~]# systemctl restart docker

在这里插入图片描述

[root@bogon ~]# docker pull 192.168.122.33/library/centos-nginx:v1
v1: Pulling from library/centos-nginx
8ba884070f61: Already exists
b49e39a48ce9: Pull complete
ee8f9e32e5d1: Pull complete
76444f96007d: Pull complete
3a3e79f9d90d: Pull complete
Digest: sha256:b51c09890e5dca970a846012c05123b8eeab9e55a3ea7b94408ae42c718389d9
Status: Downloaded newer image for 192.168.122.33/library/centos-nginx:v1

[root@bogon ~]# docker run -d 192.168.122.33/library/centos-nginx:v1
21cb5b28b3eda91c18df68d613afe8fcb7ee92b75032728fe6204d3e7f4033ea

[root@bogon ~]# curl http://172.17.0.2
nginx s running!!!

九、docker容器网络

9.1 本地网络

9.1.1 bridge

所有容器连接到桥,就可以使用外网,使用NAT让容器可以访问外网

[root@bogon ~]# ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
group default
link/ether 02:42:0d:52:fa:0a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:dff:fe52:fa0a/64 scope link
valid_lft forever preferred_lft forever

#所有容器连接到此桥,IP地址都是172.17.0.0/16
#启动docker服务后出现
[root@bogon ~]# brctl show
bridge name bridge id STP enabled interfaces
br-5ca493f64e19 8000.02429cb0e393 no
docker0 8000.02420d52fa0a no

[root@bogon ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
93283dec7d39 bridge bridge local

#使用--network选择完成对容器网络的选择
[root@bogon ~]# docker run -d --network bridge smartgodocker/centos-nginx:v1

每一台docker host上的docker0所在网段完全一样。

9.1.2 host

所有的容器与docker host在同一网络中,可以让容器访问,甚至可以让外网主机访问容器中的服务

[root@bogon ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
51ab732381e8 host host local

使用–network选择容器运行的网络

[root@bogon ~]# docker run -it --network host centos:latest /bin/bash

[root@bogon /]# ip a s
bash: ip: command not found

[root@bogon /]# yum -y install iproute
#安装完成后,查看IP地址,发现其使用了docker host地址
#好处在于方便访问
#坏处在多容器同时运行一种服务,端口冲突
#仅在测试环境中使用

9.1.3 none

容器仅与lo网卡,不能与外界连接,在高级应用中会使用到

[root@bogon ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
93283dec7d39 bridge bridge local
5ca493f64e19 harbor_harbor bridge local
51ab732381e8 host host local
4b7fd7698bec none null local

[root@bogon ~]# docker run -it --network none centos:latest

[root@8159e9d168ab /]# ip a s
#无法验证

9.1.4 容器网络或联盟网络

容器间共享同一个网络命名空间,实现容器间数据传输

9.2 跨主机容器间网络

9.2.1 实现跨主机容器间通信的工具

  • Pipework
  • Flannel
  • Weave
  • Open V Switch OVS
  • Calico

9.2.1 Flannel工作原理

  • 是Overlay网络,即覆盖型网络
  • 通过etcd保存子网信息及网络分配信息
  • 给每台Docker Host分配置一个网段
  • 通过UDP传输数据包

9.2.2 配置flannel

9.2.2.1 环境说明
  • node1
    • 安装软件 etcd flannel docker
  • node2
    • 安装软件 flannel docker
9.2.2.2 主机配置
  • 主机名
[root@bogon ~]# hostnamectl set-hostname node1
[root@bogon ~]# hostnamectl set-hostname node2
  • 配置/etc/hosts
    所有主机
[root@bogon ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.122.33 node1
192.168.122.33 etcd
192.168.122.185 node2`在这里插入代码片`
  • 安全配置

所有主机

[root@bogon ~]# systemctl stop firewalld
[root@bogon ~]# systemctl disable firewalld
[root@bogon ~]# sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
  • 安装软件

node1

[root@node1 ~]# yum -y install etcd flannel

node2

[root@node2 ~]# yum -y install flannel
  • 配置etcd及flannel

node1

etcd配置

[root@node1 ~]# cat /etc/etcd/etcd.conf
#[Member]
#ETCD_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001" #修改
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="default"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#ETCD_MAX_REQUEST_BYTES="1572864"
#ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
#ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
#ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
#
#[Clustering]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://etcd:2379,http://etcd:4001" #修改
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"
#ETCD_ENABLE_V2="true"
#
#[Proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[Security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[Logging]
#ETCD_DEBUG="false"
#ETCD_LOG_PACKAGE_LEVELS=""
#ETCD_LOG_OUTPUT="default"
#
#[Unsafe]
#ETCD_FORCE_NEW_CLUSTER="false"
#
#[Version]
#ETCD_VERSION="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#
#[Profiling]
#ETCD_ENABLE_PPROF="false"
#ETCD_METRICS="basic"
#
#[Auth]
#ETCD_AUTH_TOKEN="simple"

开启etcd服务

[root@node1 ~]# systemctl enable etcd
Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to
/usr/lib/systemd/system/etcd.service.
[root@node1 ~]# systemctl start etcd
[root@node1 ~]# ss -anput | grep ":2379"
tcp ESTAB 0 0 127.0.0.1:49946 127.0.0.1:2379
users:(("etcd",pid=17487,fd=11))
tcp LISTEN 0 128 :::2379 :::*
users:(("etcd",pid=17487,fd=6))
tcp ESTAB 0 0 ::ffff:127.0.0.1:2379
::ffff:127.0.0.1:49946 users:(("etcd",pid=17487,fd=15))
[root@node1 ~]# ss -anput | grep ":4001"
tcp ESTAB 0 0 127.0.0.1:34450 127.0.0.1:4001
users:(("etcd",pid=17487,fd=13))
tcp LISTEN 0 128 :::4001 :::*
users:(("etcd",pid=17487,fd=7))
tcp ESTAB 0 0 ::ffff:127.0.0.1:4001
::ffff:127.0.0.1:34450 users:(("etcd",pid=17487,fd=14))

验证etcd

#测试etcd是否存取数据
[root@node1 ~]# etcdctl set testdir/testkey0 1000
1000
[root@node1 ~]# etcdctl get testdir/testkey0
1000
#检查集群是否健康
[root@node1 ~]# etcdctl -C http://etcd:4001 cluster-health
member 8e9e05c52164694d is healthy: got healthy result from http://etcd:2379
cluster is healthy
[root@node1 ~]# etcdctl -C http://etcd:2379 cluster-health
member 8e9e05c52164694d is healthy: got healthy result from http://etcd:2379
cluster is healthy

flannel配置

[root@node1 ~]# cat /etc/sysconfig/flanneld
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379" #注意此处配置
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network" #记得默认前缀
# Any additional options that you want to pass
#FLANNEL_OPTIONS=""

在etcd中添加网段

[root@node1 ~]# etcdctl mk /atomic.io/network/config '{ "Network": "172.20.0.0/16" }'
{ "Network": "172.20.0.0/16" }
[root@node1 ~]# etcdctl get /atomic.io/network/config
{ "Network": "172.20.0.0/16" }

启动flannel

[root@node1 ~]# systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to
/usr/lib/systemd/system/flanneld.service.
Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to
/usr/lib/systemd/system/flanneld.service.
[root@node1 ~]# systemctl start flanneld
[root@node1 ~]# ip a s
65: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast
state UNKNOWN group default qlen 500
link/none
inet 172.20.22.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::841:71ef:e238:b38b/64 scope link flags 800
valid_lft forever preferred_lft forever

配置flannel与docker结合

第一步:subnet信息

[root@node1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.20.0.0/16
FLANNEL_SUBNET=172.20.22.1/24 #使用
FLANNEL_MTU=1472 #使用
FLANNEL_IPMASQ=false

第二步:配置docker daemon

[root@node1 ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.122.33"],
"registry-mirrors":
["https://s27w6kze.mirror.aliyuncs.com","https://registry.docker-cn.com"],
"bip": "172.20.22.1/24",
"mtu": 1472
}

第三步:重启docker

[root@node1 ~]# systemctl restart docker

启动容器验证网络

[root@node1 harbor]# ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
group default
link/ether 02:42:0d:52:fa:0a brd ff:ff:ff:ff:ff:ff
inet 172.20.22.1/24 brd 172.20.22.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:dff:fe52:fa0a/64 scope link
valid_lft forever preferred_lft forever
65: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast
state UNKNOWN group default qlen 500
link/none
inet 172.20.22.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::841:71ef:e238:b38b/64 scope link flags 800
valid_lft forever preferred_lft forever
[root@node1 harbor]# docker run -it centos:latest /bin/bash
[root@2468256e467a /]#
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID":
"a9ab0cd178d55c2e5e3c963d5791a4ad2659932167da81781cc5d961ea3e9aa0",
"EndpointID":
"62de9679127a393344e7caccaaafcf05fe297f67ede24bc1230e5e62cf48958a",
"Gateway": "172.20.22.1",
"IPAddress": "172.20.22.2",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:14:16:02",
"DriverOpts": null

node2

配置flannel

[root@node2 ~]# cat /etc/sysconfig/flanneld
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
[root@node2 ~]# systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to
/usr/lib/systemd/system/flanneld.service.
Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to
/usr/lib/systemd/system/flanneld.service.
[root@node2 ~]# systemctl start flanneld
[root@node2 ~]# ip a s
6: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state
UNKNOWN group default qlen 500
link/none
inet 172.20.13.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::3999:4299:7371:99ba/64 scope link flags 800
valid_lft forever preferred_lft forever

配置flannel与docker结合

第一步:获取subnet信息

[root@node2 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.20.0.0/16
FLANNEL_SUBNET=172.20.13.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false

第二步:修改docker daemon配置文件

[root@node2 ~]# cat /etc/docker/daemon.json
{
"insecure-registries": ["http://192.168.122.33"],
"bip": "172.20.13.1/24",
"mtu": 1472
}

第三步:重启docker

[root@node2 ~]# systemctl restart docker

第四步:开启容器验证

[root@node2 ~]# ip a s
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
group default
link/ether 02:42:fb:d8:68:65 brd ff:ff:ff:ff:ff:ff
inet 172.20.13.1/24 brd 172.20.13.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:fbff:fed8:6865/64 scope link
valid_lft forever preferred_lft forever
6: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state
UNKNOWN group default qlen 500
link/none
inet 172.20.13.0/16 scope global flannel0
valid_lft forever preferred_lft forever
inet6 fe80::3999:4299:7371:99ba/64 scope link flags 800
valid_lft forever preferred_lft forever


[root@node2 ~]# docker run -it centos:latest /bin/bash
[root@4cf2859ec3bf /]#
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID":
"ae12e0c00f2108e3192fc6792c45ccc9bf1460c8562806c6bd4d22335fd71659",
"EndpointID":
"8e2d68167b16e1317b86262312f9677acdc2e3c2f47c5601fe5016969029f898",
"Gateway": "172.20.13.1",
"IPAddress": "172.20.13.2",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:14:0d:02",
"DriverOpts": null

大大的注意项
如发现各容器内分配的ip之间相互ping不通,可能由于防火墙问题引起的,执行下面操作即可:

[root@node1 ~]# iptables -P INPUT ACCEPT
[root@node1 ~]# iptables -P FORWARD ACCEPT
[root@node1 ~]# iptables -F
[root@node1 ~]# iptables -L -n
[root@node2 ~]# iptables -P INPUT ACCEPT
[root@node2 ~]# iptables -P FORWARD ACCEPT
[root@node2 ~]# iptables -F
[root@node2 ~]# iptables -L -n

十、容器编排部署

10.1 编排部署作用

  • 实现复杂容器应用架构之间的互联
  • 减少大量容器部署的成本
    在这里插入图片描述

10.2 编排部署工具

  • docker machine
    • 用于准备docker host
      在这里插入图片描述
  • docker compose
    通过一个文件定义复杂的容器应用之间的关系
  • docker swarm
    • 用于管理docker host
    • 把docker host生成一个集群
    • 可以使用YAML文件实现复杂容器应用编排
  • kubernetes
    • 简称 k8s
    • google公司内部使用十几年伯格系统的开源
    • 归云原生计算基金会
    • 能够实现复杂容器应用的编排部署
    • 容器自动装箱功能
    • 容器滚动更新及回滚
    • 容器水平扩展
    • 配置中心
    • 密钥和存储管理
    • 容器云平台使用kubernetes完成核心功能
      • openshift
      • rancher
  • mesos + marathon
    • mesos 集群资源管理
    • marathon 容器编排部署

10.3 docker-compose

10.3.1 docker compose 作用

在一个文件中定义复杂的容器应用之间的关系,用一个命令即可执行

  • YAML,类似于html,xml
  • YAML格式文件
  • docker-compose 使用yaml文件启动容器
    • start & stop
    • down & up

10.3.2 docker compose定义方法

容器分三层:

  • 工程 project 一个目录
  • 服务 service 用于定义容器资源(镜像、网络、依赖、容器)
  • 容器 container 用于运行服务

步骤:
1、创建一个目录
2、创建一个docker-compose.yaml文件,定义服务
3、使用docker-compose命令启动服务

10.3.3 docker-compose工具部署

[root@node2 ~]# yum -y install epel-release
[root@node2 ~]# yum -y install python2-pip
[root@node2 ~]# pip install --upgrade pip
[root@node2 ~]# pip install docker-compose

10.3.4 使用docker-compose部署应用案例

10.3.4.1 案例一

使用haproxy实例web应用发布
在这里插入图片描述
步骤:

第一步:创建一个工程

[root@node1 ~]# mkdir docker-haproxy
[root@node1 ~]# cd docker-haproxy/
[root@node1 docker-haproxy]#

第二步:定义web服务

[root@node1 docker-haproxy]# mkdir web
[root@node1 docker-haproxy]# cd web
[root@node1 web]# cat Dockerfile
FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py

[root@node1 web]# cat index.py
#!/usr/bin/python
#date:
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import socket
import fcntl
import struct
import pickle
from datetime import datetime
from collections import OrderedDict
class HandlerClass(SimpleHTTPRequestHandler):
def get_ip_address(self,ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
def log_message(self, format, *args):
if len(args) < 3 or "200" not in args[1]:
return
try:
request = pickle.load(open("pickle_data.txt","r"))
except:
request=OrderedDict()
time_now = datetime.now()
ts = time_now.strftime('%Y-%m-%d %H:%M:%S')
server = self.get_ip_address('eth0')
host=self.address_string()
addr_pair = (host,server)
if addr_pair not in request:
request[addr_pair]=[1,ts]
else:
num = request[addr_pair][0]+1
del request[addr_pair]
request[addr_pair]=[num,ts]
file=open("index.html", "w")
file.write("<!DOCTYPE html> <html> <body><center><h1><font color=\"blue\"
face=\"Georgia, Arial\" size=8><em>HA</em></font> Webpage Visit Results</h1>
</center>");
for pair in request:
if pair[0] == host:
guest = "LOCAL: "+pair[0]
else:
guest = pair[0]
if (time_now-datetime.strptime(request[pair][1],'%Y-%m-%d
%H:%M:%S')).seconds < 3:
file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +":
<font color=\"red\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font
color=\"blue\">"+guest+"</font>&gt to WebServer &lt<font color=\"blue\">"+pair[1]+"
</font>&gt</p>")
else:
file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +":
<font color=\"maroon\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font
color=\"navy\">"+guest+"</font>&gt to WebServer &lt<font color=\"navy\">"+pair[1]+"
</font>&gt</p>")
file.write("</body> </html>");
file.close()
pickle.dump(request,open("pickle_data.txt","w"))
if __name__ == '__main__':
try:
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
addr = len(sys.argv) < 2 and "0.0.0.0" or sys.argv[1]
port = len(sys.argv) < 3 and 80 or int(sys.argv[2])
HandlerClass.protocol_version = Protocol
httpd = ServerClass((addr, port), HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
except:
exit()

第三步:定义haproxy服务

[root@node1 docker-haproxy]# mkdir haproxy
[root@node1 docker-haproxy]# cd haproxy/
[root@node1 haproxy]# cat haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen stats
bind *:70
stats enable
stats uri /
frontend balancer
bind 0.0.0.0:80
mode http
default_backend web_backends
backend web_backends
mode http
option forwardfor
balance roundrobin
server weba weba:80 check
server webb webb:80 check
server webc webc:80 check
option httpchk GET /
http-check expect status 200

第四步:创建docker-compose.yaml文件整合以上服务

[root@node1 docker-haproxy]# cat docker-compose.yaml
weba:
build: ./web
expose:
- 80
webb:
build: ./web
expose:
- 80
webc:
build: ./web
expose:
- 80
haproxy:
image: haproxy:latest
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- weba
- webb
- webc
ports:
- "80:80"
- "70:70"
expose:
- "80"
- "70"

第五步:使用docker-compose命令启动工程

[root@node1 docker-haproxy]# pwd
/root/docker-haproxy
[root@node1 docker-haproxy]# docker-compose up

第六步:访问
在这里插入图片描述
在这里插入图片描述

10.3.4.2 案例二

创建一个python web应用,使用flask,把用户访问的次数写入到redis,通过web首页显示访问次数。

第一步:创建一个工程目录

[root@node1 ~]# mkdir pythondir
[root@node1 ~]# cd pythondir
[root@node1 pythondir]#

第二步:创建一个应用

[root@node1 pythondir]# cat app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis',port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello world! I have been seen %s time.' % redis.get('hits')
if __name__ == "__main__":
app.run(host="0.0.0.0",debug=True)

创建安装的软件需求列表

[root@node1 pythondir]# cat requirements.txt
flask
redis

第三步:Dockerfile文件

[root@node1 pythondir]# cat Dockerfile
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py

第四步:创建docker-compose.yaml文件

[root@node1 pythondir]# cat docker-compose.yaml
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
depends_on:
- redis
redis:
image: redis:latest

第五步:运行

[root@node1 pythondir]# pwd
/root/pythondir
[root@node1 pythondir]# docker-compose up

第六步:访问
在这里插入图片描述

10.3.4.3 案例三

使用容器运行一个wordpress应用

  • 语言开发环境
  • 数据库

第一步:创建一个工程目录

[root@node1 ~]# mkdir wordpress
[root@node1 ~]# cd wordpress
[root@node1 wordpress]#

第二步:创建一个docker-compose.yaml文件

[root@node1 wordpress]# cat docker-compose.yaml
version: '2'
services:
db:
image: mysql:5.7
volumes:
- "./.data/db:/var/lib/mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
links:
- db
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: wordpress

第三步:验证

[root@node1 ~]# cd wordpress/
[root@node1 wordpress]# ls -a
. .. .data docker-compose.yaml
[root@node1 wordpress]# ls .data/
db
[root@node1 wordpress]# ls .data/db/
auto.cnf client-key.pem ib_logfile1 private_key.pem sys
ca-key.pem ib_buffer_pool ibtmp1 public_key.pem wordpress
ca.pem ibdata1 mysql server-cert.pem
client-cert.pem ib_logfile0 performance_schema server-key.pem

第四步:访问
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

10.4 docker swarm

10.4.1 docker swarm介绍

10.4.1.1 是什么
  • 是docker host集群管理工具
  • docker官方提供的
  • docker 1.12版本以后
  • 用来统一集群管理的,把整个集群资源做统一调度
  • 比kubernetes要轻量化
  • 实现scaling 规模扩大或缩小
  • 实现rolling update 滚动更新或版本回退
  • 实现service discovery 服务发现
  • 实现load balance 负载均衡
  • 实现route mesh 路由网格,服务治理
10.4.1.2 docker swarm架构
  • 节点 (node) 就是一台docker host

    • 管理节点(manager node) 负责管理集群中的节点并向工作节点分配任务
    • 工作节点(worker node) 接收管理节点分配的任务,运行任务
  • 服务(services),在工作节点运行的,由多个任务共同组成

  • 任务(task),运行在工作节点上容器或容器中包含应用,是集群中调度最小管理单元

在这里插入图片描述

10.4.2 docker swarm部署环境准备

10.4.2.1 准备主机
  • 3台主机
  • centos7.6
  • cpu、memory、disk不做要求
10.4.2.2 准备ip及主机名
[root@nodeX ~]# hostnamectl set-hostname nodeX
[root@nodeX ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE="Ethernet"
BOOTPROTO="static"
NAME="eth0"
DEVICE="eth0"
ONBOOT="yes"
IPADDR="192.168.122.xxx"
PREFIX="24"
GATEWAY="192.168.122.1"
DNS1="119.29.29.29"
[root@nodeX ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.122.100 node1
192.168.122.110 node2
192.168.122.120 node3
10.4.2.3 安全准备
#ntp
[root@nodeX ~]# crontab -e
0 */1 * * * ntpdate time1.aliyun.com
#firewalld
[root@nodeX ~]# systemctl stop firewalld;systemctl disable firewalld
#selinux 需要重启系统
[root@nodeX ~]# sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
10.4.2.4 准备docker
[root@nodeX ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

[root@nodeX ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

[root@nodeX ~]# yum -y install docker-ce

[root@node1 ~]# cat /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd #删除-H(含)后面所有内容
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

[root@nodeX ~]# systemctl enable docker;systemctl start docker

10.4.3 docker swarm集群部署

10.4.3.1 角色划分

在这里插入图片描述

10.4.3.2 集群初始化
[root@node1 ~]# docker swarm init --listen-addr 192.168.122.100:2377
Swarm initialized: current node (5agiwlur6fziotng0y7art7ti) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-
3p19n7axxygdhbg4debkqc5395pdqevll9x6zxm5tqrnrxmmi4-as8fhsxxuiqpr2bzxxuc88m9p
192.168.122.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the
instructions.

可以支持多master节点

10.4.3.3 添加工作节点到swarm集群

node2-node3

[root@nodeX ~]# docker swarm join --token SWMTKN-1-3p19n7axxygdhbg4debkqc5395pdqevll9x6zxm5tqrnrxmmi4-as8fhsxxuiqpr2bzxxuc88m9p 192.168.122.100:2377
[root@node1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY
MANAGER STATUS ENGINE VERSION
5agiwlur6fziotng0y7art7ti * node1 Ready Active
Leader 18.09.5
kodqq1taqnn2jyz9zl2vjus1j node2 Ready Active
18.09.5
x21s1j3hx78nztrrs4v4iuf28 node3 Ready Active
18.09.5

10.4.4 docker swarm应用

10.4.4.1 镜像准备

v1

[root@node1 nginxtest]# pwd
/root/nginxtest
[root@node1 nginxtest]# cat index.html
nginx is running!!! v1
[root@node1 nginxtest]# cat Dockerfile
FROM centos:latest
MAINTAINER "smartaiops<smartaiops@126.com>"
RUN yum -y install yum-plugin-ovl && yum -y install epel-release
RUN yum -y install nginx
ADD index.html /usr/share/nginx/html/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
CMD /usr/sbin/nginx
[root@node1 nginxtest]# docker build -t 192.168.122.100/library/centos-nginx:v1 .
[root@node1 nginxtest]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
192.168.122.100/library/centos-nginx v1 7bd2f64fcec4 About a
minute ago 466MB
[root@node1 nginxtest]# docker login http://node1
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@node1 nginxtest]# docker push 192.168.122.100/library/centos-nginx:v1

v2

[root@node1 nginxtest]# cat index.html
nginx is running!!! v2
[root@node1 nginxtest]# docker build -t 192.168.122.100/library/centos-nginx:v2 .
Sending build context to Docker daemon 3.072kB
Step 1/8 : FROM centos:latest
---> 9f38484d220f
Step 2/8 : MAINTAINER "smartaiops<smartaiops@126.com>"
---> Using cache
---> 793dcb13fe22
Step 3/8 : RUN yum -y install yum-plugin-ovl && yum -y install epel-release
---> Using cache
---> 36423e32ea59
Step 4/8 : RUN yum -y install nginx
---> Using cache
---> e960a535ab1d
Step 5/8 : ADD index.html /usr/share/nginx/html/
---> b105fbc8ea0b
Step 6/8 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
---> Running in 39acb9a6047f
Removing intermediate container 39acb9a6047f
---> 0923f79dcaca
Step 7/8 : EXPOSE 80
---> Running in 3b117cc735f8
Removing intermediate container 3b117cc735f8
---> 5397260f3cec
Step 8/8 : CMD /usr/sbin/nginx
---> Running in 436eff3f5775
Removing intermediate container 436eff3f5775
---> feb45843edff
Successfully built feb45843edff
Successfully tagged 192.168.122.100/library/centos-nginx:v2
[root@node1 nginxtest]# docker push 192.168.122.100/library/centos-nginx:v2

在这里插入图片描述

10.4.4.2 发布一个服务

在manager node上

[root@node1 ~]# docker service create --replicas 2 --publish 8090:80 --name nginxsvc
192.168.122.100/library/centos-nginx:v1
qu78yi4an2i640kyyhapma8yo
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service converged
  • 验证
[root@node1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
PORTS
qu78yi4an2i6 nginxsvc replicated 2/2
192.168.122.100/library/centos-nginx:v1 *:8090->80/tcp
[root@node1 ~]# docker service ps nginxsvc
ID NAME IMAGE NODE
DESIRED STATE CURRENT STATE ERROR PORTS
k7cmbni9gezt nginxsvc.1 192.168.122.100/library/centos-nginx:v1
node2 Running Running 2 minutes ago
p25jcebm3tq1 nginxsvc.2 192.168.122.100/library/centos-nginx:v1
node1 Running Running 3 minutes ago
  • 扩展或缩小
[root@node1 ~]# docker service scale nginxsvc=3
nginxsvc scaled to 3
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged

或

[root@node1 ~]# docker service scale nginxsvc=1
nginxsvc scaled to 1
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
[root@node1 ~]# docker service ps nginxsvc
ID NAME IMAGE NODE
DESIRED STATE CURRENT STATE ERROR PORTS
k7cmbni9gezt nginxsvc.1 192.168.122.100/library/centos-nginx:v1
node2 Running Running 9 minutes ago
  • 滚动更新或版本回退
[root@node1 ~]# docker service update --image 192.168.122.100/library/centos-nginx:v2
nginxsvc
nginxsvc
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged

在这里插入图片描述
间隔更新方法

[root@node1 ~]# docker service update --replicas 3 --image 192.168.122.100/library/centos-nginx:v2 --update-parallelism 1 --update-delay 30s nginxsvc
  • 删除
[root@node1 ~]# docker service rm nginxsvc
nginxsvc
[root@node1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
PORTS

10.4.5 存储卷应用

  • 持久化存储使用
10.4.5.1 本地卷
[root@node1 ~]# docker service create --replicas 1 --mount
"type=bind,source=$PWD,target=/abc" --publish 8081:80 --name cnginxsvc
192.168.122.100/library/centos-nginx:v1
eezhdem1fwli0wa58e4vmwoak
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
[root@node1 ~]# docker service ps cnginxsvc
ID NAME IMAGE NODE
DESIRED STATE CURRENT STATE ERROR PORTS
ctk7nswxmzqt cnginxsvc.1 192.168.122.100/library/centos-nginx:v1
node1 Running Running 47 seconds ago
[root@node1 ~]# docker exec cnginxsvc.1.ctk7nswxmzqtuwtl0twstwf9y ls /abc
anaconda-ks.cfg
centos.tar
docker-compose.yaml
harbor
harbor-offline-installer-v1.7.5.tgz
nginx.tar
nginxtest
portainer.tar
visualizer.tar
#
[root@node1 ~]# docker service scale cnginxsvc=3
cnginxsvc scaled to 3
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged
[root@node1 ~]# docker service ps cnginxsvc
ID NAME IMAGE NODE
DESIRED STATE CURRENT STATE ERROR
PORTS
ctk7nswxmzqt cnginxsvc.1 192.168.122.100/library/centos-nginx:v1
node1 Running Running 5 minutes ago
9dfxbyl8mieb cnginxsvc.2 192.168.122.100/library/centos-nginx:v1
node2 Running Running about a minute ago
y0xf1xefiurj cnginxsvc.3 192.168.122.100/library/centos-nginx:v1
node3 Running Running about a minute ago
[root@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
bf3334199443 192.168.122.100/library/centos-nginx:v1 "/bin/sh -c /usr/sbi…"
2 minutes ago Up About a minute 80/tcp
cnginxsvc.2.9dfxbyl8mieb1cr5bcfezby5h
[root@node2 ~]# docker exec bf333 ls /abc
anaconda-ks.cfg
node2.txt
[root@node3 ~]# touch node3.txt
[root@node3 ~]# docker ps
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
eef61182c176 192.168.122.100/library/centos-nginx:v1 "/bin/sh -c /usr/sbi…"
2 minutes ago Up 2 minutes 80/tcp
cnginxsvc.3.y0xf1xefiurjj6hlxkgmdaj8q
[root@node3 ~]# docker exec eef6 ls /abc
anaconda-ks.cfg
node3.txt
10.4.5.2 网络存储卷
  • 实现跨docker host之间容器数据共享
  • 持久化保存网络服务器中

第一步:创建nfs服务

node3上完成nfs服务

#所有节点均安装
[root@nodeX ~]# yum -y install nfs-utils rpcbind
#创建共享目录
[root@node3 ~]# mkdir /opt/dockervolume
#共享
[root@node3 ~]# cat /etc/exports
/opt/dockervolume *(rw,sync,no_root_squash)
#输出共享
[root@node3 ~]# exportfs -rv
exporting *:/opt/dockervolume
[root@node3 ~]# systemctl enable rpcbind nfs-server
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to
/usr/lib/systemd/system/nfs-server.service.
[root@node3 ~]# systemctl start rpcbind nfs-server
[root@node3 ~]# systemctl status rpcbind nfs-server
#查看是否共享
[root@node3 ~]# cat /var/lib/nfs/etab
/opt/dockervolume *
(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,s
ecure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,n
o_all_squash)

第二步:在docker swarm中创建volume

#查看卷列表
[root@node1 ~]# docker volume ls
DRIVER VOLUME NAME
local 1e43364d8093004c63da5db7620b0173951eb8fc6c9350fd1ae3eec975b89203
local 6d5ab4ce239c8662ef91d920697045087d1725d3292f5af23f5ff649d715333d
local 49e2b7a92e65863eea49f79cfb27821e97032abab87a8665c9e26810be9057fa
local 90b0437f701a74fa5296deac14e31cf560cc235f98b4ec2b585dcf29e4bc46ba
local 586ffd04cf12bfa1774a284247fb8b0347413a5a83c0597595629d0388c8290d
local 633c6fb7a889e30c3791adf9e0db821ed7bd1aca4464d42d7055bb7ef587a758
local 665c7d39ceb6d5b600f1ab6e49a9035def5435d0fd46edbb001dded6686ee2d3
local a06e038abbb7fc766852f138fabfa4aafe8f0bc193bd68d4a96c3541ae755622
local dcf83c973c4574dfec91c611e0eaae59181aa52304ac56a8f90147ff96b5c5ba
local e7802d2eb9f16ce8aa85b0d8c2fc265c4414719ef2f5a0fe90509cd797b8474f
[root@node1 ~]# docker volume create --driver local --opt type=nfs --opt
o=addr=192.168.122.120,rw --opt device=:/opt/dockervolume smartgovolume1
smartgovolume1
[root@node1 ~]# docker volume ls
DRIVER VOLUME NAME
local 1e43364d8093004c63da5db7620b0173951eb8fc6c9350fd1ae3eec975b89203
local 6d5ab4ce239c8662ef91d920697045087d1725d3292f5af23f5ff649d715333d
local 49e2b7a92e65863eea49f79cfb27821e97032abab87a8665c9e26810be9057fa
local 90b0437f701a74fa5296deac14e31cf560cc235f98b4ec2b585dcf29e4bc46ba
local 586ffd04cf12bfa1774a284247fb8b0347413a5a83c0597595629d0388c8290d
local 633c6fb7a889e30c3791adf9e0db821ed7bd1aca4464d42d7055bb7ef587a758
local 665c7d39ceb6d5b600f1ab6e49a9035def5435d0fd46edbb001dded6686ee2d3
local a06e038abbb7fc766852f138fabfa4aafe8f0bc193bd68d4a96c3541ae755622
local dcf83c973c4574dfec91c611e0eaae59181aa52304ac56a8f90147ff96b5c5ba
local e7802d2eb9f16ce8aa85b0d8c2fc265c4414719ef2f5a0fe90509cd797b8474f
local smartgovolume1
[root@node1 ~]# docker volume inspect smartgovolume1
[
{
"CreatedAt": "2019-04-30T10:36:21+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/smartgovolume1/_data",
"Name": "smartgovolume1",
"Options": {
"device": ":/opt/dockervolume",
"o": "addr=192.168.122.120,rw",
"type": "nfs"
},
"Scope": "local"
}
]
[root@node2 ~]# docker volume create --driver local --opt type=nfs --opt
o=addr=192.168.122.120,rw --opt device=:/opt/dockervolume smartgovolume1
smartgovolume1
[root@node3 ~]# docker volume create --driver local --opt type=nfs --opt
o=addr=192.168.122.120,rw --opt device=:/opt/dockervolume smartgovolume1
smartgovolume1
#手动发布服务时需要在集群中每台主机添加volume

第三步:使用docker service发布服务时使用volume

  • 手动启动service时使用volume
    前题条件是nfs服务已经被挂载到本地
    创建多副本时需要在每个容器运行的docker hosts上添加volume
[root@node1 ~]# docker service create --replicas 3 --publish 81:80 --mount
"type=volume,source=smartgovolume1,target=/usr/share/nginx/html" --name cnginxsvcvolume-test 192.168.122.100/library/centos-nginx:v1
nczb5rj8uggnz0z9jvteuecbm
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged
[root@node3 ~]# echo "volume test" >> /opt/dockervolume/index.html
[root@node3 ~]# echo "volume test" >> /opt/dockervolume/index.html
您在 /var/spool/mail/root 中有新邮件
[root@node3 ~]# ls /opt/dockervolume/
404.html 50x.html index.html nginx-logo.png poweredby.png
[root@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
c4c05052354d 192.168.122.100/library/centos-nginx:v1 "/bin/sh -c /usr/sbi…"
33 seconds ago Up 32 seconds 80/tcp cnginxsvc-volumetest.3.ohbwdb4hfcnjiogyl5c2et3dw
[root@node2 ~]# docker exec c4c0 cat /usr/share/nginx/html/index.html
nginx is running!!! v1
volume test
[root@node3 ~]# docker ps
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
27a0eb22ead8 192.168.122.100/library/centos-nginx:v1 "/bin/sh -c /usr/sbi…"
3 minutes ago Up 3 minutes 80/tcp cnginxsvc-volumetest.1.jqt4gl5xwtcy4uxtf0rrv9nm9
[root@node3 ~]# docker exec 27a0 cat /usr/share/nginx/html/index.html
nginx is running!!! v1
volume test

在这里插入图片描述
修改nfs服务器上目录内容,再次验证。

[root@node3 ~]# echo "AAAA" > /opt/dockervolume/index.html

在这里插入图片描述

  • 使用编排部署方式使用volume

请清除上一次实验创建的网络存储卷挂载

[root@nodeX ~]# docker volume rm smartgovolume1
smartgovolume1
#所有节点

第一步:编排部署文件

[root@node1 nginx-volume]# cat nginx-volume.yaml
version: '3.3'
services:
cnginxsvc:
image: 192.168.122.100/library/centos-nginx:v1
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
ports:
- "81:80"
volumes:
- "smartgovolume1:/usr/share/nginx/html"
volumes:
smartgovolume1:
driver: local
driver_opts:
type: "nfs"
o: "addr=192.168.122.120,rw"
device: ":/opt/dockervolume"

第二步:使用docker stack发布服务

[root@node1 nginx-volume]# docker stack deploy -c nginx-volume.yaml nginx-stack
Creating network nginx-stack_default
Creating service nginx-stack_cnginxsvc
[root@node1 nginx-volume]# docker stack ls
NAME SERVICES ORCHESTRATOR
nginx-stack 1 Swarm
[root@node1 nginx-volume]# docker stack services nginx-stack
ID NAME MODE REPLICAS
IMAGE PORTS
l8t8q0my72hv nginx-stack_cnginxsvc replicated 3/3
192.168.122.100/library/centos-nginx:v1 *:81->80/tcp
[root@node1 ~]# docker volume ls
DRIVER VOLUME NAME
local 1e43364d8093004c63da5db7620b0173951eb8fc6c9350fd1ae3eec975b89203
local 6d5ab4ce239c8662ef91d920697045087d1725d3292f5af23f5ff649d715333d
local 49e2b7a92e65863eea49f79cfb27821e97032abab87a8665c9e26810be9057fa
local 90b0437f701a74fa5296deac14e31cf560cc235f98b4ec2b585dcf29e4bc46ba
local 586ffd04cf12bfa1774a284247fb8b0347413a5a83c0597595629d0388c8290d
local 633c6fb7a889e30c3791adf9e0db821ed7bd1aca4464d42d7055bb7ef587a758
local 665c7d39ceb6d5b600f1ab6e49a9035def5435d0fd46edbb001dded6686ee2d3
local a06e038abbb7fc766852f138fabfa4aafe8f0bc193bd68d4a96c3541ae755622
local dcf83c973c4574dfec91c611e0eaae59181aa52304ac56a8f90147ff96b5c5ba
local e7802d2eb9f16ce8aa85b0d8c2fc265c4414719ef2f5a0fe90509cd797b8474f
local nginx-stack_smartgovolume1
[root@node2 ~]# docker volume ls
DRIVER VOLUME NAME
local nginx-stack_smartgovolume1
[root@node3 ~]# docker volume ls
DRIVER VOLUME NAME
local nginx-stack_smartgovolume1
[root@node3 ~]# ls /opt/dockervolume/
404.html 50x.html index.html nginx-logo.png poweredby.png

在这里插入图片描述

10.5 docker stack

10.5.1 是什么

  • 早期使用service发布,每次只能发布一个service
  • yaml可以发布多个服务,但是使用docker-compose只能在一台主机发布
  • 借助docker swarm同时发布多服务
  • 是docker生态service发布的最高层次

10.5.2 案例

目标:

  1. 远程管理docke host
  2. 监控docker host上运行的容器
[root@node1 ~]# cat docker-compose.yaml
version: "3"
services:
nginx:
image: nginx:alpine
ports:
- 80:80
deploy:
mode: replicated
replicas: 4
visualizer:
image: dockersamples/visualizer
ports:
- "9001:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
portainer:
image: portainer/portainer
ports:
- "9000:9000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
  • docker stack 运行多服务
[root@node1 ~]# docker stack deploy -c docker-compose.yaml stack-demo
Creating network stack-demo_default
Creating service stack-demo_portainer
Creating service stack-demo_nginx
Creating service stack-demo_visualizer
[root@node1 ~]# docker stack ls
NAME SERVICES ORCHESTRATOR
stack-demo 3 Swarm

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/90049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java+Servlet电商购物系统(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频&#xff0c;手把手带同学们敲代码从0到1完成项目 该项目采用技术MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程。 项目涉及的技术&#xff1a; 1、前端&#xff1a;JSP、css、Javascrip…

Java类型转换

java是一门强类型语言&#xff0c;当不同类型之间的变量相互赋值时&#xff0c;会有严格的校验。当类型不一致时&#xff0c;就会发生类型的转换。java中类型转换分为两类&#xff1a;自动类型转换和强制类型转换。 造型(casting)的含义是把一种类型的值赋给另一种类型的变量。…

可视化项目管理,项目进度管理必备工具

一个项目能不能成功&#xff0c;其实在开始时就决定了&#xff0c;计划是否完善&#xff0c;任务是否明确决定着项目能否顺利进行。 同时&#xff0c;在项目进行过程中&#xff0c;也要监控项目的进度以确保每项工作都能按进度进行&#xff0c;必须不断掌握计划的实施情况。 …

计算机毕业设计django基于python教学互动系统

项目介绍 在各学校的教学过程中,教学互动管理是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及,“基于网络的学习模式”正悄无声息的改变着传统的教室学习模式,“基于网络的教学互动平台”的研究和设计也成为教育技术领域的热点课题。采用当前流行的B/S模式以及3…

人工智能学习:倒立摆强化学习控制-Policy Gradient(11)

相对于DQN输出采取动作的Q值&#xff0c;Policy Gradient网络输出采取动作的概率&#xff0c;根据概率来判断需要采取的动作&#xff0c;并在训练过程不断修正网络&#xff0c;使输出的概率更好的符合最优的采取动作的策略。关于Policy Gradient方法的详细原理&#xff0c;可以…

[附源码]计算机毕业设计的汽车租赁系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

配置虚拟主机

配置虚拟主机 虚拟主机在一台Web 服务器上&#xff0c;可以为多个独立的IP地址、域名或端口号提供不同的Web 站点。对于访问量不大的站点来说&#xff0c;这样做可以降低单个站点的运营成本。 子任务1 配置基于IP地址的虚拟主机 基于IP地址的虚拟主机的配置需要在服务器上…

详解STM32启动文件

本文对STM32启动文件startup_stm32f10x_hd.s的代码进行讲解&#xff0c;此文件的代码在任何一个STM32F10x工程中都可以找到。 启动文件使用的ARM汇编指令汇总 Stack——栈 Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGNStack_Mem SPACE Stack_Size__initi…

nodejs安装及环境配置

node.js下载 地址&#xff1a;https://nodejs.org/en/download/ 如果要下载指定的版本&#xff0c;可以点击下面的链接。 开始安装 双击msi&#xff0c;开始安装node.js。 点击【Next】按钮 勾选复选框&#xff0c;点击【Next】按钮 修改好目录后&#xff0c;点击【Nex…

大三学生HTML期末作业,网页制作作业——HTML+CSS+JavaScript饮品饮料茶(7页)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

vuex配置项(核心概念),vuex的触发流程

1.vuex中有哪些配置项&#xff08;核心概念&#xff09;作用是什么 state作用&#xff1a; 负责存储数据 getters作用&#xff1a;state计算属性(有缓存) mutaions作用&#xff1a;负责同步更新state数据 mutaions是唯一可以修改state数据的方式 actions作用&#xff1a;负责…

当AI学会创作,是否应该感到担忧?

当AI学会创作&#xff0c;是否应该感到担忧&#xff1f;0. 前言1. 人工智能与 AIGC1.1 人工智能简介1.2 人工智能与 AIGC1.3 步入 AIGC 时代2. 文本生成模型3. 代码生成模型4. 图像生成模型小结与展望0. 前言 近来&#xff0c;随着 Open AI 发布的新一代 AI 聊天机器人 ChatGP…

【Redis】Redis 持久化(RDB和AOF)

文章目录概述RDB触发机制如何恢复 rdb 文件&#xff1f;RDB 优点&#xff1a;RDB 缺点&#xff1a;AOFAOF 优点AOF 缺点概述 Redis 是内存数据库&#xff0c;如果不将内存中的数据库状态保存到磁盘&#xff0c;那么服务器一旦进程退出&#xff0c;服务器中的数据库状态也会消失…

软件供应链安全状况报告

根据 ReversingLabs 于 2022 年 12 月 5 日发布的报告《软件供应链安全状况》&#xff08;文末提供报告阅读地址&#xff09; &#xff0c;在 2020 年至 2022 年初供应链攻击呈指数级增长之后&#xff0c;企业在整个2022 年出现了缓慢但稳定的增长。 ReversingLabs的研究基于上…

深证L2接口是如何运营的?

深证L2接口是现在大数据时代常用的一种程序接口&#xff0c;它集程序与协议于一体&#xff0c;为用户提供他们所需要的数据&#xff0c;这大大提高了用户的交易效率。 深证L2接口是如何运营的&#xff1f; 首先就是获取股票数据运用得最频繁的领域&#xff0c;股票交易市场领…

看完这篇还不懂 MySQL 的 MVCC 机制算我输

前言 MySQL中大名鼎鼎的MVCC机制想必大家都有所耳闻吧&#xff0c;虽然在平时MySQL使用过程中基本上用不到&#xff0c;但是面试中出场率十分高&#xff0c;而且作为架构师的你也是需要知道它的工作机制。那么你对MVCC机制了解多少呢&#xff1f;MVCC机制是用来干嘛的呢&#…

判断链表是否有环,如果有返回环的入口,即链表有环证明,和找到环的入口证明(非常清晰的证明过程)

有环链表 判断一个链表有环&#xff0c;如果有环&#xff0c;返回起点 使用快慢指针的方式&#xff0c;两个指针同时指向头节点&#xff0c;慢指针low一次走一步&#xff0c;快指针fast一次走两步&#xff0c;只要low和fast相遇即说明链表有环 只要快指针和慢指针有相差的步…

Maven Javafx javafx-maven-plugin打包项目,添加dll文件

在pom.xml的 javafx-maven-plugin内添加 additionalAppResources&#xff0c;并进行重新加载 <plugin><groupId>com.zenjava</groupId><artifactId>javafx-maven-plugin</artifactId><version>8.8.3</version><configuration&g…

2022,软件测试真的有说的这么容易吗?

前言 大家都说软件测试入门容易&#xff0c;似乎软件测试成了跳进互联网生态圈的最佳途径。但是不少小伙伴在入门软件测试后&#xff0c;却变的相当的迷茫&#xff0c;不知道自己应该做什么&#xff0c;似乎点点点就成了工作中唯一的事情了。趁现在负能量还没有缠身的时候&…

服务优化实践

性能分析常用方法 1. top top指令默认用来监控cpu使用情况&#xff0c;根据cpu使用情况&#xff0c;分析整个系统运作情况&#xff08;大多数系统cpu密集型&#xff09;top指令查询的进程&#xff0c;将会根据cpu使用率大小进行排序&#xff0c;使用的比较多的排在前面&#x…