背景
最近遇到一个docker compose部署的产品(旧版本)想部署到k8s中,而该产品应用的多个容器都在docker compose中设置了ip地址,镜像里的应用配置也是配置的这些预设ip,容器之间通过预设IP进行通信。
但是该产品的云化已经在最新版本中完成,并做了大量修改。现在希望对那个旧版本以最小成本部署到k8s中就行,也就是不想动产品应用的镜像,仅仅修改部署方式。
产品应用的docker compose定义
代码语言:javascript复制version: "3.4"
services:
db:
image: "db"
container_name: "db"
restart: always
networks:
internal:
ipv4_address: 169.254.253.2
app:
image: "app"
container_name: "app"
depends_on:
- db
network_mode:
"service:db"
app1:
image: "app1"
container_name: "app1"
depends_on:
- app
networks:
internal:
ipv4_address: 169.254.253.7
app2:
image: "app2"
container_name: "app2"
depends_on:
- db
restart: always
networks:
internal:
ipv4_address: 169.254.253.11
networks:
internal:
external: true
- 所有容器都连接到外部创建的一个网络
internal
,这个网络定义了子网范围,这些容器能够互相通信 - app容器使用db的网络,共享network namespace
如何部署到K8S中
- 如果每个容器部署到单独的Pod中,那么Pod之间通信就只能通过service或者pod的cluster IP。
- 使用service就需要更改调用地址
- 使用pod的cluster IP,就意味着需要指定pod的cluster IP为docker compose里的预设IP。这需要配置CNI,但是k8s环境是客户的,不方便修改。
- 如果把所有容器部署到一个Pod里,网络修改的影响范围就小了。
Pod网络:在k8s中,pod的所有容器都在同一个network namespace,只分配了一个cluster IP。无法为每个容器设置单独的IP地址。
方案一:修改容器配置文件里的调用地址
通过挂载configmap去覆盖包含预设IP的配置文件。
由于存在硬编码预设IP的情况,无法修改编译产物,此方案不适用。
方案二:所有容器部署到同一个Pod,给容器单独设置IP
- 前面提过,在pod中是无法为容器单独设置IP地址的。这里想到个取巧的方法。
- 给容器的lo网络接口设置多IP,让所有docker compose里的预设IP都指向localhost,这样所有容器就能通过这些预设IP进行通信。并且在Pod中,这个操作对所有容器可见。
给lo网络接口设置多IP
- 通过
ip addr
查看网络接口信息 - 给lo网络接口添加一个 IP 地址
ip addr add 169.254.253.2/24 dev lo scope host
scope host
: 这表示该 IP 地址的范围是主机(host),即这是一个本地回环地址。这样的地址只在本地计算机上可见,不会通过网络接口发送到物理网络。
- 查看是否生效
现在,可以通过169.254.253.2访问到localhost。
将这部分操作,放到Pod的initContainer里
代码语言:javascript复制 initContainers:
- name: init-network
image: xxx
imagePullPolicy: Always
securityContext:
privileged: true
command: ["/bin/bash","-c"]
args: ["ip addr add 169.254.253.2/24 dev lo scope host && ip addr add 169.254.253.3/24 dev lo scope host && ip addr add 169.254.253.4/24 dev lo scope host && ip addr add 169.254.253.5/24 dev lo scope host && ip addr add 169.254.253.6/24 dev lo scope host && ip addr add 169.254.253.7/24 dev lo scope host && ip addr add 169.254.253.12/24 dev lo scope host"]
到此,所有产品应用镜像不用修改,也能通过之前的预设IP进行通信。
方案缺点
- 无法对单个容器进行扩缩容
- 因为在同一个network namespace中,所有容器不能端口冲突
- 产品容器里的预设IP不能和k8s内部网段冲突
Post Views: 6