(高可用)七、Docker

docker

一、基础

  • 配置docker的yum源
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0

[centos]
name=extras
baseurl=https://mirrors.aliyun.com/centos/7/extras/x86_64
gpgcheck=0

  • 修改配置,开机自启
[root@localhost ~]# systemctl enable --now docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
  • 基本命令
[root@localhost ~]# docker search  kaminskypavel/mario
[root@localhost ~]# docker pull kaminskypavel/mario
[root@localhost ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED       SIZE
kaminskypavel/mario   latest    9a35a9e43e8c   7 years ago   198MB
[root@localhost ~]# docker history kaminskypavel/mario
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
9a35a9e43e8c   7 years ago   /bin/sh -c #(nop) CMD ["python3" "-m" "http.…   0B
<missing>      7 years ago   /bin/sh -c #(nop) EXPOSE 8080/tcp               0B
<missing>      7 years ago   /bin/sh -c #(nop) WORKDIR /app                  0B
<missing>      7 years ago   /bin/sh -c #(nop) COPY dir:02930d36f63824e72…   9.81MB
<missing>      7 years ago   /bin/sh -c apt-get install -y python3           0B
<missing>      7 years ago   /bin/sh -c #(nop) MAINTAINER Pavel 'PK' Kami…   0B
<missing>      7 years ago   /bin/sh -c #(nop) CMD ["/bin/bash"]             0B
<missing>      7 years ago   /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   1.9kB
<missing>      7 years ago   /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli…   195kB
<missing>      7 years ago   /bin/sh -c #(nop) ADD file:5a3f9e9ab88e725d6…   188MB


[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                                         NAMES
4a7d913c032b   kaminskypavel/mario   "python3 -m http.ser…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp, 8080/tcp   mariogame
[root@localhost ~]# docker rm -f 4a7d913c032b
4a7d913c032b
  • 出现报错
[root@localhost ~]# docker run -d -p 9002:8080 --name mariogame --restart=always kaminskypavel/mario
e6900ab772fb7b46c8af3cc240b21b193146eaa1e7c06cc350c35649f5d3be1e
docker: Error response from daemon: driver failed programming external connectivity on endpoint mariogame (b6eca333313045bc9b8d93808c88c64b0ca233792b638149cba8bcae8b035cbd):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9002 -j DNAT --to-destination 172.17.0.2:8080 ! -i docker0: iptables: No chain/target/match by that name.
 (exit status 1)).

[root@localhost ~]# docker inspect mariogame
# 发现容器没有正常获取到IP

# iptables也没有策略
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# 重启docker服务
[root@localhost ~]# systemctl restart docker.service

# 再看iptables有策略了
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere


# 再次启动容器
[root@localhost ~]# docker run -d -p 9002:8080 --name mariogame --restart=always kaminskypavel/mario
075662a4ff79bb4b1035f458d223675ba955042874cb5427ee6d5f73265e69b5
  • 效果

二、镜像和容器

  1. 概念
    • 共享宿主机内核
    • base镜像提供最小的linux发行版
    • 容器层以下所有镜像层都是只读的
    • docker从上往下依次查找文件
    • 容器层保存镜像变化的部分,并不对镜像进行改变
    • 一个镜像最多127层
    • 容器实际上就是宿主机中的一个进程
  1. 构建镜像
    1. commit构建
# 运行容器、修改容器、将容器保存为新镜像

## 运行容器
[root@localhost ~]# docker run -it --name demo busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
205dae5015e7: Pull complete
Digest: sha256:7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c
Status: Downloaded newer image for busybox:latest
/ #
/ # ll
sh: ll: not found
/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ # touch demo1
/ # touch demo2
/ # ls
bin    demo1  demo2  dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ #

## ctrl+D退出容器,资源回收;ctrl+pq后台挂起容器
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED              STATUS                      PORTS                                       NAMES
eda375abd277   busybox               "sh"                     About a minute ago   Exited (0) 31 seconds ago                                               demo

[root@localhost ~]# docker start demo
demo
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                                       NAMES
eda375abd277   busybox               "sh"                     3 minutes ago   Up 5 seconds                                               demo
075662a4ff79   kaminskypavel/mario   "python3 -m http.ser…"   10 hours ago    Up 10 hours    0.0.0.0:9002->8080/tcp, :::9002->8080/tcp   mariogame
## 连接到后台容器
[root@localhost ~]# docker attach demo
/ #
/ #
/ # read escape sequence
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS          PORTS                                       NAMES
eda375abd277   busybox               "sh"                     4 minutes ago   Up 44 seconds                                               demo


## 修改容器,保存为新镜像
[root@localhost ~]# docker commit -m "add files" demo demo:v1
sha256:c0e76e51827a83de913a969284eff211fac9f6459acbbb478c5a7c756151ec65

[root@localhost ~]# docker history demo:v1
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
c0e76e51827a   34 seconds ago   sh                                              33B       add files
66ba00ad3de8   13 days ago      /bin/sh -c #(nop)  CMD ["sh"]                   0B
<missing>      13 days ago      /bin/sh -c #(nop) ADD file:4bd5aa84616ee9384…   4.87MB


## 查看日志
[root@localhost docker]# docker logs nginxv1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/01/17 05:31:00 [notice] 1#1: using the "epoll" event method
2023/01/17 05:31:00 [notice] 1#1: nginx/1.23.3
2023/01/17 05:31:00 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/01/17 05:31:00 [notice] 1#1: OS: Linux 3.10.0-957.el7.x86_64
2023/01/17 05:31:00 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 65536:65536
2023/01/17 05:31:00 [notice] 1#1: start worker processes
2023/01/17 05:31:00 [notice] 1#1: start worker process 29

效率低、难复现、易出错、使用者无法进行安全审计

    1. 使用DockerFile构建
      • 1、Dockerfile会打包所在目录及子目录
      • 2、常用命令:FROM(base镜像)、MAINTAINER(作者信息)、COPY(使用相对路径,原封不动)、ADD(也是拷贝,自解压,可下载远端URL)、ENV(环境变量)、EXPOSE(暴露服务接口)、VOLUME(申明数据卷,通常是挂载点,用于容器内数据的持久化)、WORKDIR(为RUN、CMD、ENTRYPOINT、ADD和COPY设定工作目录,会自动创建)、RUN(在容器里执行shell指令)、CMD和ENTRYPOINT(都用于设置容器启动后执行的命令,CMD会被RUN覆盖,ENTRYPOINT一定会执行,只有最后一个ENTRYPOINT有效)
    • 扩展nginx镜像
# 创建Dockerfile
[root@localhost docker]# vim Dockerfile

FROM nginx
COPY index.html /usr/share/nginx/html


# 创建测试页
[root@localhost docker]# vim index.html

[root@localhost docker]# docker build -t nginx:v1 .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM nginx
 ---> a99a39d070bf
Step 2/2 : COPY index.html /usr/share/nginx/html
 ---> a9734cbb4a63
Successfully built a9734cbb4a63
Successfully tagged nginx:v1
[root@localhost docker]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
nginx                 v1        a9734cbb4a63   5 seconds ago    142MB
demo                  v1        c0e76e51827a   13 minutes ago   4.87MB
nginx                 latest    a99a39d070bf   5 days ago       142MB

# 开启容器
[root@localhost docker]# docker run -d -p 80:80 --name nginxv1 nginx:v1
e7866b65faf7e4d0cb773e890588375cbee3bd96e91edb4ea1d1e0ef258637a9

效果如下:
请添加图片描述

三、Docker仓库

  1. Docker Hub
    • 需要网络,速度慢
    • 所有人都可以访问
    • 处于安全考量,镜像不能暴露在外网
  1. Docker本地仓库
    • 官方配置文档:https://docs.docker.com/registry/deploying/
# 下载registry镜像,并启动
[root@localhost docker]# docker pull registry
[root@localhost docker]# docker run -d -p 5000:5000 --restart=always --name registry registry

# push镜像
[root@localhost docker]# docker tag nginx:v1 localhost:5000/nginx:v1
[root@localhost docker]# docker push localhost:5000/nginx:v1

# pull镜像
[root@localhost docker]# docker pull localhost:5000/nginx:v1
    • 非安全本地仓库
vim /etc/docker/daemon.json
{
  "insecure-registries" : ["myregistrydomain.com:5000"]  # 填docker本地仓库服务器域名
}
    • 安全本地仓库
# 删除非安全仓库,并移除卷
[root@docker1 ~]# docker rm -f registry
registry
[root@docker1 ~]# docker volume ls
DRIVER    VOLUME NAME
local     cb60a059934b5bd020c7499c7d6e2df46dd1833189b18490ddc2d62c9c60e583
[root@docker1 ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
cb60a059934b5bd020c7499c7d6e2df46dd1833189b18490ddc2d62c9c60e583

Total reclaimed space: 56.88MB
[root@docker1 ~]# docker volume ls
DRIVER    VOLUME NAME

# 创建自签名证书
## 安装openssl11,下载地址:
## https://kojipkgs.fedoraproject.org//packages/openssl11/1.1.1k/2.el7/x86_64/openssl11-1.1.1k-2.el7.x86_64.rpm
## https://kojipkgs.fedoraproject.org//packages/openssl11/1.1.1k/2.el7/x86_64/openssl11-libs-1.1.1k-2.el7.x86_64.rpm

[root@docker1 ~]# yum install -y openssl11-libs-1.1.1k-2.el7.x86_64.rpm openssl11-1.1.1k-2.el7.x86_64.rpm

[root@docker1 ~]# openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/repo.docker.alexw.com.key --addext "subjectAltName=DNS:repo.docker.alexw.com" -x509 -days 365 -out certs/repo.docker.alexw.com.crt
Generating a RSA private key
...................................................................................++++
............................................................................................++++
writing new private key to 'certs/repo.docker.alexw.com.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:alexw
Organizational Unit Name (eg, section) []:alexw
Common Name (eg, your name or your server's hostname) []:repo.docker.alexw.com
Email Address []:

# 运行容器,并挂载签名文件路径
[root@docker1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /opt/registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/repo.docker.alexw.com.crt -e REGISTRY_HTTP_TLS_KEY=/certs/repo.docker.alexw.com.key registry
36f9d1862f07c668777560cc2caceb4a3312cf13321e0f23bf374c076eea450d

[root@docker1 ~]# docker tag nginx:latest repo.docker.alexw.com/nginx:latest
[root@docker1 ~]# docker push repo.docker.alexw.com/nginx:latest
The push refers to repository [repo.docker.alexw.com/nginx]
Get "https://repo.docker.alexw.com/v2/": x509: certificate signed by unknown authority

# 放置自签名证书到规定位置
[root@docker1 certs.d]# mkdir repo.docker.alexw.com
[root@docker1 certs.d]# cd repo.docker.alexw.com/
[root@docker1 repo.docker.alexw.com]# pwd
/etc/docker/certs.d/repo.docker.alexw.com
[root@docker1 repo.docker.alexw.com]# cp /root/certs/repo.docker.alexw.com.crt ca.crt

# 再次push
[root@docker1 repo.docker.alexw.com]# docker push repo.docker.alexw.com/nginx:latest
The push refers to repository [repo.docker.alexw.com/nginx]
80115eeb30bc: Pushed
049fd3bdb25d: Pushed
ff1154af28db: Pushed
8477a329ab95: Pushed
7e7121bf193a: Pushed
67a4178b7d47: Pushed
latest: digest: sha256:4c1c50d0ffc614f90b93b07d778028dc765548e823f676fb027f61d281ac380d size: 1570
[root@docker1 repo.docker.alexw.com]# curl -k https://repo.docker.alexw.com/v2/_catalog
{"repositories":["nginx"]}

# 远程访问配置
[root@server2 ~]# vim /etc/docker/daemon.json
{
        "registry-mirrors":["https://repo.docker.alexw.com"]
}

    • 本地Harbor仓库搭建
      • Harbor是由VMware公司开源的企业级的Docker Registry管理项目
      • 需要docker和docker-compose
      • harbor会自动创建registry容器,所以原先有的需要删除
### 安装docker-compose
### https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-linux-x86_64
[root@server1 ~]# mv docker-compose-linux-x86_64-v2.5.0 /usr/bin/docker-compose
[root@server1 ~]# chmod 755 /usr/bin/docker-compose
[root@server1 ~]# docker-compose version
Docker Compose version v2.5.0

### 生成签名文件
## 要确保Harbor读取到的认证文件和docker配置路径的认证文件一致,然后可以分发.crt文件到其他节点  
[root@docker1 ~]# yum install -y openssl11-libs-1.1.1k-2.el7.x86_64.rpm openssl11-1.1.1k-2.el7.x86_64.rpm

[root@docker1 ~]# openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/repo.docker.alexw.com.key --addext "subjectAltName=DNS:repo.docker.alexw.com" -x509 -days 365 -out certs/repo.docker.alexw.com.crt
Generating a RSA private key
...................................................................................++++
............................................................................................++++
writing new private key to 'certs/repo.docker.alexw.com.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:alexw
Organizational Unit Name (eg, section) []:alexw
Common Name (eg, your name or your server's hostname) []:repo.docker.alexw.com
Email Address []:



### 准备data目录,安装harbor
### https://github.com/vmware/harbor/releases/download/v1.1.2/harbor-online-installer-v1.1.2.tgz
[root@server1 cert]# mkdir /data/harbor -p && cd   /data/harbor
[root@server1 harbor]# tar xvf ~/harbor-offline-installer-v2.5.0.tgz
harbor/harbor.v2.5.0.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl

### 修改配置
[root@server1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@server1 harbor]# vim harbor.yml

hostname: repo.docker.alexw.com       # 本机域名
http:
  port: 80

https:
  port: 443
  certificate: /data/cert/alexw.com.crt      #证书
  private_key: /data/cert/alexw.com.key      #证书

harbor_admin_password: Harbor12345              #harbor的初始密码,初始用户admin

database:
  password: root123                              #数据库的密码
data_volume: /data/harbor/data

metric:                                         #配置监控
  enabled: true
  port: 9090
  path: /metrics


### 安装harbor,提前清除registry容器
[root@server1 harbor]# ./install.sh  --with-chartmuseum --with-trivy

测试:

  1. 镜像加速器
[root@localhost docker]# vim /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"]
}

[root@localhost docker]# systemctl daemon-reload
[root@localhost docker]# systemctl restart docker

四、Docker网络

  • 容器的IP是不固定的,只要小地址未被占用,IP就会变更为小地址
  • 默认三种模式:bridge、host、null
[root@docker1 repo.docker.alexw.com]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242767156ce       no              veth6ed92c4
[root@docker1 repo.docker.alexw.com]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
fcc4452c4694   bridge    bridge    local      ### 默认使用,桥接模式
ce343fd58ec8   host      host      local      ### 与宿主机共享ip
09c63c4e5277   none      null      local      ### 禁用

# docker默认使用的网卡是docker0,和宿主机是桥接模式,网关是172.17.0.1/16,运行的容器默认都在这个网段
[root@docker1 repo.docker.alexw.com]# ip a
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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:ae:26:1c brd ff:ff:ff:ff:ff:ff
    inet 192.168.147.138/24 brd 192.168.147.255 scope global noprefixroute dynamic ens33
       valid_lft 1499sec preferred_lft 1499sec
    inet6 fe80::37d4:a5b5:b4b6:19cc/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:76:71:56:ce 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:76ff:fe71:56ce/64 scope link
       valid_lft forever preferred_lft forever
67: veth6ed92c4@if66: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether ba:42:31:bf:54:82 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::b842:31ff:febf:5482/64 scope link
       valid_lft forever preferred_lft forever


# 与宿主机共享IP模式启动容器
[root@docker1 repo.docker.alexw.com]# docker run -d --network host --name demonginx nginx
6a3b8117dc5e7bf97bb3ac5b2a78120b77f5fb8becf344dc50b2164afa6f39ad

自定义网络

  • 三种模式:bridge(自带DNS,容器名作为域名)、overlay(用于集群)、macvlan
[root@docker1 repo.docker.alexw.com]# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

桥接模式

  • 提供DNS,容器名即域名
# 默认使用的就是桥接模式,如果不指定网段,会自动分配
[root@docker1 repo.docker.alexw.com]# docker network create testnet
6ebd82e16e6a0a54e19cb78c2abba4178582b229516d955804270959691c8a00

# 启动一个nginx容器,使用testnet
[root@docker1 repo.docker.alexw.com]# docker run -d -p 8008:80 --name web1 --network testnet nginx
208132dfb3f9b007802238eb5e5460e58f6a9550f294666edf862e3a4cf35d16
# 启动另一个容器,使用testnet
[root@docker1 repo.docker.alexw.com]# docker run -it --rm --network testnet busybox
/ #
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
75: eth0@if76: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 可以看到,域名正确解析,web1获取到172.18.0.2的地址
/ # ping web1
PING web1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.126 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.089 ms


# 自己指定网段
[root@docker1 repo.docker.alexw.com]# docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.1 newtestnet
d362aefe6a76bb3eed0cac7aacdfb2ff63a66b20c13ef3e984952604fc9ef78f

[root@docker1 repo.docker.alexw.com]# docker run -d -p 8009:80 --name web2 --network newtestnet nginx
e461b738d7dd20fac740ed706e20db983f89befd1e0d2d4071829adb997876ad
[root@docker1 repo.docker.alexw.com]# docker run -it --rm --network newtestnet busybox
/ #
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
82: eth0@if83: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.3/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping web2
PING web2 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.272 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.081 ms

配置不同网段网络互联

# web1网段172.18.0.0/16,client网段10.0.0.2/24
[root@server1 ~]# docker network connect testnet client

[root@docker1 repo.docker.alexw.com]# docker run -it --rm --name client --network newtestnet busybox
/ #
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
92: eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
92: eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
94: eth1@if95: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # ping web1
PING web1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.257 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.109 ms

joined模式

  • 容器之间可以使用同一接口接入外部服务
[root@docker1 repo.docker.alexw.com]# docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS                                             NAMES
48c8689a36ae   nginx      "/docker-entrypoint.…"   32 minutes ago   Up 32 minutes   0.0.0.0:8001->80/tcp, :::8001->80/tcp             web1
36f9d1862f07   registry   "/entrypoint.sh /etc…"   2 hours ago      Up 2 hours      0.0.0.0:443->443/tcp, :::443->443/tcp, 5000/tcp   registry
[root@docker1 repo.docker.alexw.com]# docker run -it --rm --network container:web1 --name server busybox
/ #
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
84: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.11:43100        0.0.0.0:*               LISTEN      -
tcp        0      0 :::80                   :::*                    LISTEN      -
/ #
# 自动做了hosts解析
/ # 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.18.0.2      48c8689a36ae

容器与外网通信过程

  • 出:通过iptables的SNAT实现的
  • 入:docker-proxy和SNAT
[root@docker1 repo.docker.alexw.com]# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 3 packets, 188 bytes)
 pkts bytes target     prot opt in     out     source               destination
   74  3936 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 2 packets, 104 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 102 packets, 7624 bytes)
 pkts bytes target     prot opt in     out     source               destination
   41  2484 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 103 packets, 7708 bytes)
 pkts bytes target     prot opt in     out     source               destination
   11   586 MASQUERADE  all  --  *      !br-d362aefe6a76  10.0.0.0/24          0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !br-6ebd82e16e6a  172.18.0.0/16        0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:443
    0     0 MASQUERADE  tcp  --  *      *       172.18.0.2           172.18.0.2           tcp dpt:80

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  br-d362aefe6a76 *       0.0.0.0/0            0.0.0.0/0
    0     0 RETURN     all  --  br-6ebd82e16e6a *       0.0.0.0/0            0.0.0.0/0
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0
   50  3000 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443 to:172.17.0.2:443
    0     0 DNAT       tcp  --  !br-6ebd82e16e6a *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8001 to:172.18.0.2:80

五、Docker数据卷

对比分层文件系统和数据卷

  1. docker分层系统性能差、生命周期与容器相同
  2. docker数据卷,直接mount到宿主机、和宿主机磁盘性能相同、容器删除后依然保留、仅限本地磁盘、不能随容器迁移

docker提供两种卷

  • bind mount

使用-v指定挂载,默认权限为rw。指定只读权限ro

[root@server1 website]# docker run -d -p 8001:80 --name web1 -v /opt/website:/usr/share/nginx/html -v /root/test1:/test1:rw -v /root/test2:/test2:ro nginx
097138c0bfc157f5a54baccf70bf1a89998a989ebbf1d06b13dfe18fa18e9969
  • docker managed volume

必须指定在/var/lib/docker/volumes中,不需要指定mount源,docker自动创建数据源路径。如果指向容器内已有的目录,原有数据会被复制到volume中,只能挂载目录

[root@server1 website]# docker run -d --name web2 -p 8002:80 -v /usr/share/nginx/html nginx

# 自动创建源挂载目录
[root@server1 website]# ll /var/lib/docker/volumes/8c6efd750bb393900003e3584533c176522042b12dbfa19f107fbb3e2eda1bc0/_data/
total 8
-rw-r--r--. 1 root root 497 Dec 13 07:53 50x.html
-rw-r--r--. 1 root root 615 Dec 13 07:53 index.html
[root@server1 website]# cat index.html
index from rhel7

# 指定挂载目录
[root@server1 website]# docker volume create vol1
vol1
[root@server1 website]# docker run -d -p 8003:80 --name web3 -v vol1:/usr/share/nginx/html nginx
51a0b1537488fb7a0b82ff1f17a63c99b1c1ee149fb4970fc9be5d40bf5ff73b

[root@server1 website]# ll /var/lib/docker/volumes/vol1/_data/
total 8
-rw-r--r--. 1 root root 497 Dec 13 07:53 50x.html
-rw-r--r--. 1 root root 615 Dec 13 07:53 index.html
[root@server1 website]# cat index.html
index from rhel7

# 创建容器,并挂载现有目录
[root@server1 website]# docker create --name datavol1 -v vol1:/root/test1 busybox
5ff8aace31217665882a83f67943d963e8e286be3b8e5db952d37e98e036c3ab
[root@server1 website]# docker run -it --rm --volumes-from datavol1 busybox
/ #

六、Docker安全

概念

  • linux内核的命名空间提供的容器隔离
  • linux控制组机制对容器资源的控制
  • linux内核工作机制带来的操作权限安全
  • Docker本身的抗攻击性

容器资源控制

  • Linux Cgroups(Linux Control Group),限制一个进程组能够使用的资源上限
  • Linux Cgroup给用户暴露出的操作接口是文件系统,以文件或目录的方式暴露在/sys/fs/cgroup路径
  • mount -t cgroup
[root@server1 ~]# docker run --help | grep cpu
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)

# 指定容器使用cpu的时间总量,需要--cpu-period 和--cpu-quota搭配,默认值是-1表示未设置
[root@server1 ~]# docker run -it --rm --cpu-period 100000 --cpu-quota 20000 busybox
# 配置写入在下面这个路径
[root@server1 ~]# cat /sys/fs/cgroup/cpu/docker/f035979f6c5c8cde99889183833f0166b3c022e619a8ba07b06494b5246ee5dd/cpu.cfs_quota_us
20000

# 设置容器使用cpu的优先级,默认1024
[root@server1 ~]# docker run -it -d --name os1 --cpu-shares 100  busybox

# 指定容器能使用的内存量,--memory(对应文件memory.limit_in_bytes)和--memory-swap(对应文件memory.memsw.limit_in_bytes)配合使用(如果宿主机有swap的话)
[root@server1 ~]# docker run -it --memory 200M --memory-swap 200M busybox

# 限制IO速度,当前仅对direct IO有效
[root@server1 memory]# docker run -it --name os2 --device-write-bps /dev/sda:30MB busybox
/ # dd if=/dev/zero of=bigdata bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (100.0MB) copied, 0.291955 seconds, 342.5MB/s
/ # dd if=/dev/zero of=bigdata bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (100.0MB) copied, 3.337992 seconds, 30.0MB/s

docker安全加固

  • lxcfs
[root@server1 ~]# docker run -it -m 256m\
>  -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw\
>  -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw\
>  -v  /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw\
>  -v /var/lib/lxcfs/proc/stat:/proc/stat:rw\
>  -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw\
>  -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw\
>  busybox
  • –cap-add | --cap-drop | privileged
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值