Docker创建容器时默认采用bridge网络,自行分配ip,不允许自己指定。在实际部署中,我们需要指定容器ip,不允许其自行分配ip,尤其是搭建集群时,固定ip是必须的。我们可以创建自己的bridge网络 : mynet,创建容器的时候指定网络为mynet并指定ip即可。
1.查看网络模式
docker network ls
2.创建一个新的bridge网络
docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1 mynet
3.查看网络信息
docker network inspect mynet
4.创建容器并指定容器ip
docker run -e TZ="Asia/Shanghai" --privileged -itd -h hadoop01.com --name hadoop01 --network=mynet --ip 172.18.12.1 centos /bin/bash
解释说明:--privileged (可以有很多权限)
-e TZ="Asia/Shanghai" (时区)
-h hadoop01.com (主机名)
--name hadoop01 (容器名字)
-i :开启标准输入
-it :合起来实现和容器交互的作用,运行一个交互式会话 shell
-d : 后台运行。
解释说明2 :指定端口
docker run -e TZ="Asia/Shanghai" -p 6001:22 --privileged -itd -h hadoop3 --name hadoop3 --network=mynet --ip 172.18.12.3 centos /usr/sbin/init
5.运行容器
docker exec -it hadoop3 /bin/bash
6.centos最小化安装没有ifconfig命令,可通过yum进行安装
yum install -y net-tools
7.安装ssh服务
yum install -y openssh-server
yum install -y openssh-clients
systemctl start sshd
8.新增非root用户
yum install passwd.x86_64
useradd brock
passwd brock
9.xshell连接指定端口的容器
docker 获取容器ip
Docker provides the ability to package and run an application in a loosely isolated environment called a container.
Docker提供了在松散隔离的环境(称为容器)中打包和运行应用程序的功能。
I know what you might be thinking – come on, not another post explaining what Docker is, it's everywhere these days!
我知道您可能在想什么-来吧,这是无处不在的另一篇解释Docker是什么的文章!
But don't worry, we are skipping that basic introduction. The target audience for this article should already have a basic understanding of what Docker and Containers are.
但是不用担心,我们将跳过该基本介绍。 本文的目标读者应该已经对Docker和Containers有基本的了解。
But have you ever wondered how to get a Docker Container IP Address?
但是您是否想知道如何获取Docker容器IP地址?
Docker网络解释 (Docker network explained)
First, let's understand how the Docker network works. For that we are going to focus on the default bridge
network. When you are using Docker, if you don’t specify a driver this is the type of network you are using.
首先,让我们了解Docker网络的工作方式。 为此,我们将重点关注默认bridge
网络。 使用Docker时,如果未指定驱动程序,则这是您使用的网络类型。
The bridge
network works as a private network internal to the host so containers on it can communicate. External access is granted by exposing ports to containers.
bridge
网络充当主机内部的专用网络,因此其上的容器可以进行通信。 通过将端口暴露给容器来授予外部访问权限。
Bridge networks are used when your applications run in standalone containers that need to communicate.
当您的应用程序在需要通信的独立容器中运行时,将使用网桥网络。
In the picture above db
and web
can communicate with each other on a user created bridge network called mybridge
.
在上图中, db
和web
可以在用户创建的名为mybridge
桥接网络上相互通信。
If you’ve never added a network in Docker you should see something similar to this:
如果您从未在Docker中添加网络,则应该看到类似以下内容:
-
$ docker network ls
-
NETWORK ID NAME DRIVER SCOPE
-
c3cd46f397ce bridge bridge local
-
ad4e4c24568e host host local
-
1c69593fc6ac none null local
The default bridge
network is listed, along with host
and none
. We will ignore the other two, and use the bridge
network when we get to the examples.
列出了默认的bridge
网络,以及host
和none
。 我们将忽略其他两个,并在获得示例时使用bridge
网络。
Docker容器IP地址 (Docker Container IP Address)
By default, the container is assigned an IP address for every Docker network it connects to. And each network is created with a default subnet mask, using it as a pool later on to give away the IP addresses.
默认情况下,为容器连接到的每个Docker网络分配一个IP地址。 而且,每个网络都是使用默认子网掩码创建的,以后将其用作池来分配IP地址。
Usually Docker uses the default 172.17. 0.0/16 subnet for container networking.
通常,Docker使用默认值172.17。 容器网络的0.0 / 16子网。
Now to better understand it, we will execute a real use case.
现在,为了更好地理解它,我们将执行一个实际的用例。
Docker示例 (Docker Example)
To illustrate this, we will use a Hive and Hadoop environment, containing 5 Docker Containers.
为了说明这一点,我们将使用包含5个Docker容器的Hive和Hadoop环境。
Check out the docker-compose.yml
file we are about to execute:
docker-compose.yml
出我们将要执行docker-compose.yml
文件:
-
version: "3"
-
services:
-
namenode:
-
image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8
-
volumes:
-
- namenode:/hadoop/dfs/name
-
environment:
-
- CLUSTER_NAME=test
-
env_file:
-
- ./hadoop-hive.env
-
ports:
-
- "50070:50070"
-
datanode:
-
image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8
-
volumes:
-
- datanode:/hadoop/dfs/data
-
env_file:
-
- ./hadoop-hive.env
-
environment:
-
SERVICE_PRECONDITION: "namenode:50070"
-
ports:
-
- "50075:50075"
-
hive-server:
-
image: bde2020/hive:2.3.2-postgresql-metastore
-
env_file:
-
- ./hadoop-hive.env
-
environment:
-
HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore"
-
SERVICE_PRECONDITION: "hive-metastore:9083"
-
ports:
-
- "10000:10000"
-
hive-metastore:
-
image: bde2020/hive:2.3.2-postgresql-metastore
-
env_file:
-
- ./hadoop-hive.env
-
command: /opt/hive/bin/hive --service metastore
-
environment:
-
SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432"
-
ports:
-
- "9083:9083"
-
hive-metastore-postgresql:
-
image: bde2020/hive-metastore-postgresql:2.3.0
-
volumes:
-
namenode:
-
datanode:
No one wants to read a HUGE config file, right? So here's a picture:
没有人想要读取巨大的配置文件,对吗? 所以这是一张照片:
Much better! Now let's start up those containers:
好多了! 现在让我们启动这些容器:
docker-compose up -d
We can see 5 containers:
我们可以看到5个容器:
-
$ docker ps --format \
-
"table {{.ID}}\t{{.Status}}\t{{.Names}}"
-
CONTAINER ID STATUS NAMES
-
158741ba0339 Up 1 minutes dockerhive_hive-metastore-postgresql
-
607b00c25f29 Up 1 minutes dockerhive_namenode
-
2a2247e49046 Up 1 minutes dockerhive_hive-metastore
-
7f653d83f5d0 Up 1 minutes (healthy) dockerhive_hive-server
-
75000c343eb7 Up 1 minutes (healthy) dockerhive_datanode
Next let's check our Docker networks:
接下来,让我们检查一下Docker网络:
-
$ docker network ls
-
NETWORK ID NAME DRIVER SCOPE
-
c3cd46f397ce bridge bridge local
-
9f6bc3c15568 docker-hive_default bridge local
-
ad4e4c24568e host host local
-
1c69593fc6ac none null local
Wait a minute... there's a new network called docker-hive_default
!
等等...有一个名为docker-hive_default
的新网络!
By default docker compose sets up a single network for your app. And your app’s network is given a name based on the “project name”, originated from the name of the directory it lives in.
默认情况下,docker compose为您的应用设置一个网络。 应用的网络将基于“项目名称”获得一个名称,该名称源自其所在目录的名称。
So since our directory is named docker-hive
, this explains the new network.
因此,由于我们的目录名为docker-hive
,这说明了新网络。
Next some examples on how to get the Docker IP Address.
接下来是有关如何获取Docker IP地址的一些示例。
如何获取Docker容器IP地址-示例
(How to Get A Docker Container IP Address - examples)
And now that I have your attention, we are going to unveil the mystery.
现在,请注意,我们将揭开这个谜团。
1.使用Docker Inspect (1. Using Docker Inspect)
Docker inspect is a great way to retrieve low-level information on Docker objects. You can pick out any field from the returned JSON in a fairly straightforward manner.
Docker inspect是检索有关Docker对象的低级信息的好方法。 您可以以相当简单的方式从返回的JSON中选择任何字段。
So shall we use it to get the IP Address from the dockerhive_datanode
?
那么我们是否应该使用它从dockerhive_datanode
获取IP地址?
-
$ docker inspect -f \
-
'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
-
75000c343eb7
-
172.18.0.5
Didn't you say that Docker uses the default 172.17. 0.0/16 subnet for container networking? Why is the returned IP Address: 172.18.0.5 outside it?
您不是说Docker使用默认的172.17。 用于容器网络的0.0 / 16子网? 为什么返回的IP地址: 172.18.0.5在外面?
To answer that we have to look at our network settings:
要回答这个问题,我们必须查看我们的网络设置:
-
$ docker network inspect -f \
-
'{{range .IPAM.Config}}{{.Subnet}}{{end}}' 9f6bc3c15568
-
172.18.0.0/16
We executed this example in a Compute Engine VM, and in this test, the docker network was assigned a different subnet: 172.18.0.0/16. That explains it!
我们在Compute Engine VM中执行了此示例,在此测试中,为docker网络分配了另一个子网: 172.18.0.0/16 。 这就解释了!
Furthermore, we can also lookup all IP Addresses inside the docker-hive_default
network.
此外,我们还可以在docker-hive_default
网络中查找所有IP地址。
So we don't need to look up each Container's IP individually:
因此,我们不需要单独查找每个容器的IP:
-
$ docker network inspect -f \
-
'{{json .Containers}}' 9f6bc3c15568 | \
-
jq '.[] | .Name + ":" + .IPv4Address'
-
"dockerhive_hive-metastore-postgresql:172.18.0.6/16"
-
"dockerhive_hive-metastore:172.18.0.2/16"
-
"dockerhive_namenode:172.18.0.3/16"
-
"dockerhive_datanode:172.18.0.5/16"
-
"dockerhive_hive-server:172.18.0.4/16"
If you didn't notice, we used jq help to parse the Containers
map object.
如果您没有注意到,我们使用jq帮助来解析Containers
地图对象。
2.使用Docker exec (2. Using Docker exec)
In the following example we will work with the dockerhive_namenode
.
在以下示例中,我们将使用dockerhive_namenode
。
-
$ docker exec dockerhive_namenode 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.3 607b00c25f29
3.在Docker容器内部 (3. Inside the Docker Container)
-
$ docker exec -it dockerhive_namenode /bin/bash
-
# running inside the dockerhive_namenode container
-
ip -4 -o address
-
7: eth0 inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
We can even find other containers' IP Addresses that are inside a container in the same network:
我们甚至可以找到同一网络中某个容器内其他容器的IP地址:
Data node
数据节点
-
# running inside the dockerhive_namenode container
-
ping dockerhive_datanode
-
PING dockerhive_datanode (172.18.0.5): 56 data bytes
-
64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.092 ms
Hive mestastore
蜂巢mestastore
-
# running inside the dockerhive_namenode container
-
ping dockerhive_hive-metastore
-
PING dockerhive_hive-metastore_1 (172.18.0.2): 56 data bytes
-
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.087 ms
Hive server
蜂巢服务器
-
# running inside the container
-
ping dockerhive_hive-server
-
PING dockerhive_hive-server (172.18.0.4): 56 data bytes
-
64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.172 ms
结语 (Wrap up)
All examples were executed in a linux distribution Compute Engine VM. If you execute them in macOS or Windows environments the sample commands might change a bit.
所有示例均在linux发行版Compute Engine VM中执行。 如果您在macOS或Windows环境中执行它们,示例命令可能会有所变化。
Also bear in mind that those IP Addresses in the examples given are internal to the sample docker-hive_default
network. So if you have a use case to connect to those containers externally, you would need to use the host machine's external IP (assuming that you are exposing the containers ports correctly). Or if you are using kubernetes, for instance, to manage your Docker containers, let it handle the IP Addresses for you kubernetes-expose-external-ip-address 😉.
还请记住,给出的示例中的那些IP地址在示例docker-hive_default
网络内部。 因此,如果您有用例可以从外部连接到这些容器,则需要使用主机的外部IP(假设您正确暴露了容器端口)。 或者,例如,如果您使用kubernetes来管理Docker容器,则让它为kubernetes-expose-external-ip-address handle处理IP地址。
* Illustrations from icons8.com by Murat Kalkavan.
*从插图icons8.com由穆拉特Kalkavan 。
翻译自: https://www.freecodecamp.org/news/how-to-get-a-docker-container-ip-address-explained-with-examples/
docker 获取容器ip