docker/docker-进阶.md
2025-04-04 17:31:23 +08:00

8.2 KiB
Raw Blame History

Docker 进阶


一:端口转发

使用端口转发解决容器端口访问问题

  • -p 手工指定
  • -P 随机端口

1. MySQL 应用端口转发

-p

创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。可以用多个-p指定多个端口映射关系

mysql应用端口转发:

查看本地地址:
[root@docker ~]# ip a
inet 192.168.159.131/24 brd 192.168.159.255 scope global noprefixroute ens33             

运行容器:使用-p作端口转发,把本地3307转发到容器的3306,其他参数需要查看发布容器的页面提示。

[root@docker ~]# docker run -it -d --name="mysql-v1" -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_ROOT_HOST='%' mysql:5.7

查看容器ip
[root@docker ~]# docker inspect mysql-v1 | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

登入容器mysql

[root@docker ~]# docker exec -it mysql-v1 mysql -uroot -p
...
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

远程登入

[root@docker ~]# mysql -uroot -P 3307 -h 192.168.159.131 -p
...
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

2. Redis 应用端口转发

-P

Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。

redis应用端口转发:

查看本地地址:
[root@docker ~]# ip a
inet 192.168.159.131/24 brd 192.168.159.255 scope global noprefixroute ens33

运行容器:使用-p作端口转发,把本地6380转发到容器的6379,其他参数需要查看发布容器的页面提示

[root@docker ~]# docker run -it --name="redis-v1" -p 6380:6379 redis:latest --bind 0.0.0.0

登入容器

[root@docker ~]# docker exec -it redis-v1 redis-cli 
127.0.0.1:6379>set name wxin
OK

远程登入

[root@docker ~]# redis-cli -h 192.168.159.131 -p 6380
192.168.159.131:6380> get name
"wxin"

Docker 私有仓库

1. 仓库镜像

Docker hub官方已提供容器镜像registry,用于搭建私有仓库

拉取镜像

# docker pull daocloud.io/library/registry:latest

2. 运行容器

# docker run --name "pri_registry" --restart=always -d -p 5000:5000 daocloud.io/library/registry

注:如果创建容器不成功,报错防火墙,解决方案如下

# systemctl stop firewalld
# yum install iptables
# systemctl start iptables
# iptables -F
# systemctl restart docker

3. 查看容器

# docker ps
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS   PORTS   NAMES
1f444285bed8     daocloud.io/library/registry  "/entrypoint.sh /etc/"  23 seconds ago    Up 21 seconds    0.0.0.0:5000->5000/tcp  elegant_rosalind

4. 连接容器查看端口状态

# docker exec -it  1f444285bed8  /bin/sh    //这里是sh 不是bash
  /# netstat -lnp                        //查看5000端口是否开启
  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address      Foreign Address     State    PID/Program name   
  tcp     0    0 :::5000         :::*           LISTEN    1/registry
  Active UNIX domain sockets (only servers)
  Proto RefCnt Flags    Type    State     I-Node PID/Program name   Path

在本机查看能否访问该私有仓库, 看看状态码是不是200

# curl  -I  127.0.0.1:5000   //参数是大写的i
HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Thu, 08 Oct 2020 05:34:32 GMT

5. 仓库功能测试

为了方便下载1个比较小的镜像buysbox

# docker pull busybox

上传前必须给镜像打tag 注明ip和端口

# docker tag busybox  本机IP端口/busybox

这是直接从官方拉的镜像,很慢:

# docker tag busybox 192.168.245.136:5000/busybox

下面这个Mysql是我测试的第二个镜像从daocloud拉取的

# docker tag daocloud.io/library/mysql 192.168.245.136:5000/daocloud.io/library/mysql

注意:

tag后面可以使用镜像名称也可以使用id,我这里使用的镜像名称,如果使用官方的镜像,不需要加前缀,但是daocloud.io的得加前缀。

修改请求方式为http

默认为https不改会报以下错误:
Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client
# vim /etc/docker/daemon.json
{ "insecure-registries":["192.168.245.136:5000"] }

重启docker:
# systemctl restart docker

上传镜像到私有仓库

# docker push 192.168.245.136:5000/busybox
# docker push 192.168.245.136:5000/daocloud.io/library/mysql

查看私有仓库里的所有镜像:

# curl 192.168.245.130:5000/v2/_catalog
{"repositories":["busybox"]}

查看私有仓库里的镜像版本:

# curl 10.11.67.110:5000/v2/busybox/tags/list
{"name":"busybox","tags":["v1","v2"]}

# curl -XGET http://10.11.67.110:3000/v2/busybox/tags/list
{"name":"busybox","tags":["v1","v2"]}
查询镜像digest_hash删除命令里边要填写的 镜像digest_hash 就是 查询结果里边 Docker-Content-Digest: 后边的内容
# curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET http://10.11.67.110:3000/v2/busybox/manifests/v1
HTTP/1.1 200 OK
Content-Length: 527
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc"
X-Content-Type-Options: nosniff
Date: Thu, 12 Nov 2020 07:29:46 GMT
删除私有库镜像
进入/etc/docker/registry/config.yml添加,在stroage后面加
delete
  enabled: true
  
修改完后重新启动容器
# curl -I -XDELETE http://10.11.67.110:3000/v2/busybox/manifests/sha256:c9249fdf56138f0d929e2080ae98ee9cb2946f71498fc1484288e6a935b5e5bc
HTTP/1.1 202 Accepted
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Thu, 12 Nov 2020 07:30:22 GMT
Content-Length: 0

查看镜像信息可以看到镜像的标签显示为空 null
# curl -XGET http://10.11.67.110:3000/v2/busybox/tags/list
{"name":"busybox","tags":null}

Docker 网络

1. 容器网络

docker安装后,默认会创建三种网络类型,bridgehostnone

显示当前网络:

[root@docker ~]# docker network list
NETWORK ID     NAME      DRIVER    SCOPE
3857f7cc9806   bridge    bridge    local
eb0052691d0f   host      host      local
46decb5eed2f   none      null      local

bridge网络桥接

默认情况下启动、创建容器都是用该模式,所以每次docker容器重启时会按照顺序获取对应ip地址,这就导致容器每次重启,ip都发生变化。

none无指定网络

启动容器时,可以通过network=nonedocker容器不会分配局域网ip

host主机网络

docker容器的网络会附属在主机上,两者是互通的。

2. 创建固定ip容器

创建自定义网络类型,并且指定网段:

[root@docker ~]# docker network create --subnet=192.168.0.0/16 staticnet

[root@docker ~]# docker network list
NETWORK ID     NAME        DRIVER    SCOPE
3857f7cc9806   bridge      bridge    local
eb0052691d0f   host        host      local
46decb5eed2f   none        null      local
ab85da59edc7   staticnet   bridge    local

通过docker network ls可以查看到网络类型中多了一个staticnet

使用新的网络类型创建并启动容器:

[root@docker ~]# docker run -it -d --name="mysql-v2" --net staticnet --ip 192.168.0.2 mysql:5.7 /bin/bash

通过docker inspect可以查看容器ip192.168.0.2,关闭容器并重启,发现容器ip并未发生改变。