前言:本文会以多个实际的线上例子,分享自己对于Docker和Podman的一点使用经验及踩过的坑,希望对读者有一点帮助。

本文bash脚本初步加工后可直接使用(兼容mac和linux系统),对于关键点会有注重说明,但是对于一些细节需要读者自行去查阅相关文档,这里不会具体展开。

一、部署Apollo

1、docker脚本

version=2.0.1
dbhost_port=host.docker.internal:3306
dbuser=root
dbpwd=xxxx docker stop apollo-configservice && docker rm apollo-configservice
docker stop apollo-adminservice && docker rm apollo-adminservice
docker stop apollo-portal && docker rm apollo-portal docker run -p 28080:8080 \
--init \
--add-host=host.docker.internal:host-gateway \
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://$dbhost_port/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=$dbuser \
-e SPRING_DATASOURCE_PASSWORD=$dbpwd \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
-d -v /tmp/logs:/opt/logs --name apollo-configservice apolloconfig/apollo-configservice:$version
sleep 30s docker run -p 28090:8090 \
--init \
--add-host=host.docker.internal:host-gateway \
--link apollo-configservice:apollo-configservice \
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://$dbhost_port/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=$dbuser \
-e SPRING_DATASOURCE_PASSWORD=$dbpwd \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
-d -v /tmp/logs:/opt/logs --name apollo-adminservice apolloconfig/apollo-adminservice:$version
sleep 30s docker run -p 28070:8070 \
--init \
--link apollo-configservice:apollo-configservice \
--add-host=host.docker.internal:host-gateway \
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://$dbhost_port/ApolloPortalDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=$dbuser \
-e SPRING_DATASOURCE_PASSWORD=$dbpwd \
-e APOLLO_PORTAL_ENVS=dev,prd \
-e DEV_META=http://host.docker.internal:28080 \
-e PRD_META=http://host.docker.internal:28080 \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
-d -v /tmp/logs:/opt/logs --name apollo-portal apolloconfig/apollo-portal:$version echo "apollo启动完成"

2、podman脚本

podman stop apollo-configservice && podman rm apollo-configservice
podman run -p 28080:8080 \
-d --rm \
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://host.containers.internal:3306/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=xxxx \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
--name apollo-configservice apolloconfig/apollo-configservice:2.0.1
sleep 30s podman stop apollo-adminservice && podman rm apollo-adminservice
podman run -p 28090:8090 \
-d --rm \
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://host.containers.internal:3306/ApolloConfigDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=xxxx \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
--name apollo-adminservice apolloconfig/apollo-adminservice:2.0.1
sleep 30s podman stop apollo-portal && podman rm apollo-portal
podman run -p 28070:8070 \
-d --rm\
-v /etc/localtime:/etc/localtime:ro \
-e SPRING_DATASOURCE_URL="jdbc:mysql://host.containers.internal:3306/ApolloPortalDB?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=xxxx \
-e APOLLO_PORTAL_ENVS=dev,prd \
-e DEV_META=http://host.containers.internal:28080 \
-e PRD_META=http://host.containers.internal:28080 \
-e ENV=dev \
-e JAVA_OPTS='-Xmx128m -Xms128m' \
--name apollo-portal apolloconfig/apollo-portal:2.0.1
sleep 30s
echo "apollo启动完成"

3、注意事项

  1. docker里面容器可以通过 host.docker.internal 来访问宿主机,而podman容器里面是通过 host.containers.internal 来访问宿主机,注意区分。

  2. docker里面可以通过 --link 参数来连接两个容器的网络,使得容器之间可以互相通过 --name 指定的容器名 + 端口来访问。但podman不行,即使显式指定 --hostname 也不行。podman两个容器之间只能通过 ip 地址来访问,可以用 --ip 参数显式指定ip。ip的网段是10.88.0.0/16,个数为2^16 - 2 = 65536 -2 = 65534个 。

  3. 对于第2条,在mac高版本上是不适用的(即容器之间可以通过hostname来访问),虽然翻遍了官方文档,也没找到支持的论据,只能怀疑是高版本的feature(linux podman版本4.4.1,mac podman版本4.8.3)。

  4. 不要使用docker-compose,自己写bash脚本更为灵活自主可控。

  5. podman和docke命令可以互相替换,一般来说podman已经内置了命令转换功能,如果没有的话,可以通过下面代码来实现在脚本中的命令互换(脚本跟命令行的实现方式不一样)

#!/bin/bash
# 参考链接:https://blog.51cto.com/u_15162069/2780080?articleABtest=1
# 已前置设置 alias docker=podman
shopt -s expand_aliases
source ~/.bash_profile
alias
# 使用which命令判断命令是否存在
if which docker >/dev/null 2>&1; then
echo "use docker"
else
echo "use podman replace docker"
docker -v
fi
# put your docker or podman command in here

二、部署kafka

1、docker脚本

docker stop zookeeper && docker rm zookeeper
# https://hub.docker.com/r/bitnami/zookeeper
docker run -d --name zookeeper \
-p 2181:2181 \
--network=common_container_network \
-v /home/data/docker/bitnami/zookeeper:/bitnami \
-e TZ=CST-8 \
-e ALLOW_ANONYMOUS_LOGIN=YES \
bitnami/zookeeper:3.9
sleep 5s docker stop kafka && docker rm kafka
docker run -d --name kafka \
-p 19092:19092 \
--network=common_container_network \
-v /home/data/docker/bitnami/kafka:/bitnami \
-e KAFKA_HEAP_OPTS='-Xmx512m -Xms512m' \
-e KAFKA_CFG_NODE_ID=0 \
-e TZ=CST-8 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 \
-e KAFKA_CFG_LISTENERS=INTERNAL://:9092,EXTERNAL://:127.0.0.1:19092 \
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \
-e KAFKA_CFG_ADVERTISED_LISTENERS=INTERNAL://:9092,EXTERNAL://127.0.0.1:19092 \
-e KAFKA_CFG_LISTENERS=INTERNAL://:9092,EXTERNAL://:19092 \
-e KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL \
bitnami/kafka:3.4 sleep 20s docker stop kafka-exporter && docker rm kafka-exporter
docker run -d --name kafka-exporter \
--restart=no \
--network=common_container_network \
-u root \
-p 19308:19308 \
danielqsj/kafka-exporter:v1.7.0 \
--web.listen-address=:19308 \
--kafka.server=kafka:9092 \
--kafka.version=3.4.1

2、podman脚本

docker stop zookeeper && docker rm zookeeper
podman run -d --name=zookeeper --ip=10.88.222.1\
-p 2181:2181 \
-v /home/data/docker/bitnami:/bitnami \
-e TZ=CST-8 \
-e ALLOW_ANONYMOUS_LOGIN=YES \
bitnami/zookeeper:3.9
sleep 5s docker stop kafka && docker rm kafka
docker run -d --name=kafka --ip=10.88.222.2 \
-p 19092:19092 \
-v /home/data/docker/bitnami:/bitnami \
-e KAFKA_HEAP_OPTS='-Xmx512m -Xms512m' \
-e KAFKA_CFG_NODE_ID=0 \
-e TZ=CST-8 \
-e KAFKA_CFG_ZOOKEEPER_CONNECT=10.88.222.1:2181 \
-e KAFKA_CFG_LISTENERS=INTERNAL://:9092,EXTERNAL://:172.18.159.144:19092 \
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \
-e KAFKA_CFG_ADVERTISED_LISTENERS=INTERNAL://:9092,EXTERNAL://47.119.23.205:19092 \
-e KAFKA_CFG_LISTENERS=INTERNAL://:9092,EXTERNAL://:19092 \
-e KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL \
bitnami/kafka:3.4
sleep 10s docker stop kafka-exporter && docker rm kafka-exporter
docker run -d --name kafka-exporter \
--restart=no \
-u root \
-p 19308:19308 \
danielqsj/kafka-exporter:v1.7.0 \
--web.listen-address=:19308 \
--kafka.server=10.88.222.2:9092 \
--kafka.version=3.4.1

3、注意事项

  1. 注意bitnami的镜像都是rootless,但在笔者mac下,无论怎样做(已尽最大努力尝试,建议直接放弃),都不能实现文件的正确挂载。linux可以正常挂载。
  2. docker只有容器的概念,而podman里面有 容器Pod 的概念。多个容器可以在同一个pod,由pod统一管理端口映射,且pod里面容器共享网络,此时容器直接可以直接通过localhost + 端口来互相访问。
  3. 注意对于kafka的一些设置,KAFKA_CFG_ADVERTISED_LISTENERS 用于设置暴露在外网的连接地址,KAFKA_CFG_LISTENERS 用于设置暴露在内网的连接地址,这两个地址都会注册到zk上。
  4. kafka其实也可以不依赖zk,高版本已经内置KRaft(v2.8+),成熟度不详。
  5. --param 参数如果放在镜像名称之前,代表docker的参数设置,之后,则是对于镜像的参数设置。

三、部署Prometheus

1、docker脚本

docker stop prometheus && docker rm prometheus
# prometheus
docker run -d \
--restart=no \
-u root \
--name prometheus \
--network=common_container_network \
--add-host=host.docker.internal:host-gateway \
-p 19090:19090 \
-v /home/data/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /home/data/docker/prometheus/data:/prometheus \
-v /etc/localtime:/etc/localtime:ro \
prom/prometheus:v2.37.0 \
--storage.tsdb.retention.time=30d \
--storage.tsdb.path=/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-lifecycle \
--web.listen-address=:19090 docker stop alertmanager && docker rm alertmanager
# alertmanager
docker run -d \
--restart=no \
-u root \
--name alertmanager \
--network=common_container_network \
--add-host=host.docker.internal:host-gateway \
-p 19093:19093 \
-v /home/data/docker/prometheus/alertmanager:/etc/prometheus/alertmanager \
-v /etc/localtime:/etc/localtime:ro \
prom/alertmanager:v0.25.0 \
--config.file=/etc/prometheus/alertmanager/alertmanager.yml \
--storage.path="/etc/prometheus/alertmanager" \
--data.retention=120h \
--web.listen-address=:19093 docker stop node-exporter && docker rm node-exporter
# node-exporter
docker run -d --name=node-exporter \
--restart=no \
-u root \
--network=common_container_network \
--add-host=host.docker.internal:host-gateway \
-p 19100:19100 \
-v "/proc:/host/proc" \
-v "/sys:/host/sys" \
-v "/:/rootfs" \
prom/node-exporter:v1.6.0 \
--path.rootfs=/host \
--web.listen-address=:19100 \
--path.procfs /host/proc --path.sysfs /host/sys \
--collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"

2、podman脚本

docker stop prometheus && docker rm prometheus
docker run -d --rm \
--restart=no \
-u root \
--name prometheus \
-p 19090:19090 \
-v /home/data/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /home/data/docker/prometheus/data:/prometheus \
-v /etc/localtime:/etc/localtime:ro \
prom/prometheus:v2.37.0 \
--storage.tsdb.retention.time=30d \
--storage.tsdb.path=/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-lifecycle \
--web.listen-address=:19090 docker stop alertmanager && docker rm alertmanager
docker run -d --rm \
--restart=no \
-u root \
--name alertmanager \
-p 19093:19093 \
-v /home/data/docker/prometheus/alertmanager:/etc/prometheus/alertmanager \
-v /etc/localtime:/etc/localtime:ro \
prom/alertmanager:v0.25.0 \
--config.file=/etc/prometheus/alertmanager/alertmanager.yml \
--storage.path="/etc/prometheus/alertmanager" \
--data.retention=120h \
--web.listen-address=:19093 docker stop node-exporter && docker rm node-exporter
docker run -d --name=node-exporter \
--restart=no \
-u root \
-p 19100:19100 \
-v "/proc:/host/proc" \
-v "/sys:/host/sys" \
-v "/:/rootfs" \
prom/node-exporter:v1.6.0 \
--path.rootfs=/host \
--web.listen-address=:19100 \
--path.procfs /host/proc --path.sysfs /host/sys \
--collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"

3、部署grafana

# docker和grafana可以混用
# 可以对配置文件进行充分定制
docker stop grafana && docker rm grafana
docker run -d --restart=no \
-u root \
--name=grafana \
-v /home/data/docker/grafana/grafana.ini:/etc/grafana/grafana.ini \
-p 13000:13000 \
-v /etc/localtime:/etc/localtime:ro \
grafana/grafana-enterprise:10.2.3 \
--config=/etc/grafana/grafana.ini

有一说一,grafana是真的香,功能是真的多。后面就直接使用grafana内置功能来做监控报表的数据展示了,不单独写UI界面了,敬请期待~

四、相关命令汇总

以下是一些可能会经常用到的命令,这里也简单列一下:

# 间接实现多行注释
if false; then
# 快速运行
docker run -d -p 19093:19093 --name alertmanager prom/alertmanager:v0.25.0
# 查看镜像详细信息
docker inspect grafana
# 进入镜像命令行
docker exec -it grafana sh
# 查看日志
docker logs grafana
# 查看容器详细信息
docker stats grafana
# 复制目录到远程服务器
scp -r /Users/huangkui/work/online/docker/apollo root@110.42.230.56:/home/data/docker
# 复制远程服务器文件到本地
scp -r root@110.42.230.56:/usr/lib/bin/jmap /Users/huangkui/work/xiaokui/docker/apollo/prd
# 从容器内部复制文件出来
docker cp 04b4dd7569cf:/apollo/scripts/startup.sh /Users/huangkui/work/docker/apollo
# 复制文件到容器内部去
docker cp /Users/huangkui/work/xiaokui/docker/apollo/jmap apollo:/usr/lib/jvm/jre/bin
# 重启服务 Prometheus
curl -XPOST http://localhost:19090/-/reload
# 重启服务 AlertManager
curl -XPOST http://localhost:19093/-/reload
# 输入指定字符到文件
echo "hello world" >> test.txt
# 修改文件夹所有者
sudo chown -R 1001:1001 /Users/huangkui/home/data/docker/bitnami
# 修改文件权限
sudo chmod -R 777 /Users/huangkui/home/data/docker/bitnami
# 停止然后移除容器,不建议使用--rm参数,当容器启动异常时会丢失日志信息
docker stop grafana && docker rm grafana
fi

五、一键部署脚本

暂未发现其必要性,待补充。

欢迎关注微信公众号:好看的HK,第一时间掌握Java最新黑科技,轻轻松松进大厂!

对于Docker和Podman的一点使用经验的更多相关文章

  1. Docker Vs Podman

    翻译自 Chetansingh 2020年4月24日的博文<Docker Vs Podman> [1] 容器化的一场全新革命是从 Docker 开始的,Docker 的守护进程管理着所有的 ...

  2. Docker 与 Podman 容器管理的比较

    翻译自 Paul Ferrill 2020年9月1日的文章<Compare Docker vs. Podman for container management> [1] Docker 和 ...

  3. openMP的一点使用经验【非原创】

    按照百科上说的,针对于openmp的编程,最简单的就是在开头加个#include<omp.h>,然后在后面的for上加一行#pragma omp parallel for即可,下面的是较为 ...

  4. openMP的一点使用经验

    最近在看多核编程.简单来说,由于现在电脑CPU一般都有两个核,4核与8核的CPU也逐渐走入了寻常百姓家,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生.按照我的理解,多核编程可 ...

  5. 关于图像读取函数imread()的一点使用经验,注意默认参数的赋值

    读入数字图像到数组,用CNN进行训练,发现关于图像读取的一个问题. 问题描述:读取灰度数字图像,在验证时发现存在错误,从图像到数组中的值不完全一样? main code as follows: int ...

  6. 关于 WinScp 的一点使用经验

    在嵌入式平台下 是,使用SSH登陆,可以使用WinScp提供的图形界面,支持拖拽,鼠标直接打开,甚是好用. 使用WinScp 登陆的方式有,Scp和sftp两种,之前一只用scp,但后来出现了如下错误 ...

  7. Podman and Buildah for Docker users

    转自:https://developers.redhat.com/blog/2019/02/21/podman-and-buildah-for-docker-users/ I was asked re ...

  8. 选择 podman 的理由, 以及它和 Kubernetes , Docker 的区别

    转载自https://zhuanlan.zhihu.com/p/506265757 前言 大家好,我是 Liangdi, podman 4.x 版本已经发布了, 我也从 docker 开始向 podm ...

  9. 下一代容器架构已出,Docker何去何处?看看这里的6问6答!!

    我猜很多人一看这个标题已经感觉很懵逼了,什么?下一代容器都出来了,我还没学Docker呢!!! 咳咳~~在这里我给大家做一个保证,下一代容器目前也只是各个公司在测试阶段,Github上面也有很多Iss ...

  10. Podman 快速入门

    今天在某云上新购一台云服务器,发现已经有了 CentOS8.2 官方镜像可选,出于对新鲜事物的好奇,我决定开始采用 CentOS8.2,即使我还没有为它的新特性做好准备. 我的应用主要以单机版容器为主 ...

随机推荐

  1. Scala 可变数组ArrayBuffer

    1 package chapter07 2 3 import scala.collection.mutable 4 import scala.collection.mutable.ArrayBuffe ...

  2. 网络设备性能指标之pps

    基本概念: Bps:Byte per second 每秒传输多少字节 bps: bits per second 每秒传输多少位 ,这个也叫做端口速率 pps:Packet Per Second(包每秒 ...

  3. 前端使用 Konva 实现可视化设计器(1)

    使用 konva 实现一个设计器交互,首先考虑实现设计器的画布. 一个基本的画布: [展示]网格.比例尺 [交互]拖拽.缩放 "拖拽"是无尽的,"缩放"是基于鼠 ...

  4. DEB打包教程

    一.deb简介 deb是一种安装包的格式,linux上常见的安装包主要是deb.rpm 二.deb简单使用 # deb安装 sudo dpkg -i webcamera_1.0_amd64.deb # ...

  5. Java List集合去重、过滤、分组、获取数据、求最值、合并、排序、跳数据和遍历

    前言 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i. 准备工作:现有一个User类.Student 类和Ticket类,加入相关依赖 @Data public class User { / ...

  6. 安装pnpm 和报错解决,亲测可行

    安装pnpm 和报错解决,亲测可行 pnpm 是一款磁盘空间高效的软件包管理器. 当使用 npm 或 Yarn 时,如果你有 1000个项目,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要 ...

  7. HarmonyOS Lottie组件,让动画绘制更简单

    原文:https://mp.weixin.qq.com/s/eC7g9ya4f_2AiNgteiyXcw,点击链接查看更多技术内容. 动画是UI界面的重要元素之一,精心设计的动画能使UI界面更直观,有 ...

  8. 94个JS/eTS开源组件首发上新,肯定有你要用的一款!

    原文:https://mp.weixin.qq.com/s/6RdxNisTQoyPds811PNZKA,点击链接查看更多技术内容. 2021年的华为开发者大会(HDC2021)上,我们发布了新一代的 ...

  9. sql 语句系列(列举系列)[八百章之第八章]

    前言 这一张就是就是查询自己设计数据库的结构,对于接收一个老的项目相当重要. 列举模式中的表 查询所以表 select table_name from INFORMATION_SCHEMA.TABLE ...

  10. 力扣1068(MySQL)-产品销售分析Ⅰ(简单)

    题目: 销售表 Sales: 产品表 Product: 写一条SQL 查询语句获取 Sales 表中所有产品对应的 产品名称 product_name 以及该产品的所有 售卖年份 year 和 价格 ...