保证系统的纯净,移植常用开发工具到docker
docker常用命令
官方文档
docker run :创建一个新的容器并运行一个命令
docker exec :在运行的容器中执行命令
docker inspect : 获取容器/镜像的元数据。
我常用的alias:
1
2
3
| alias d.ps='docker ps -a'
alias d.images='docker images'
alias d.stopall='docker stop $(docker ps -aq)'
|
ETCD
官方文档
1、创建容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| REGISTRY=quay.io/coreos/etcd
DATA_DIR=/Users/XXX/dev/docker/etcd/
NODE1=0.0.0.0
docker run \
-d \
-p 2379:2379 \
-p 2380:2380 \
--volume=${DATA_DIR}:/etcd-data \
--name etcd ${REGISTRY}:latest \
/usr/local/bin/etcd \
--data-dir=/etcd-data --name node1 \
--initial-advertise-peer-urls http://${NODE1}:2380 --listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://${NODE1}:2379 --listen-client-urls http://0.0.0.0:2379 \
--initial-cluster node1=http://${NODE1}:2380
|
2、进入容器shell
1
| docker exec -it etcd /bin/sh
|
进入后就可以调用 etcdctl 进行设置 如:
1
2
| etcdctl get config/stat_platform/online
etcdctl set /config/stat_platform/online '{"KafkaBrokerList":["192.168.10.8:32769"],"Listen":":8610","LogSetting":{"LogDir":"./logs","LogFile":"stat_platform.log","LogLevel":"DEBUG"}}'
|
mysql
容器文档
1
| docker run -d -p 127.0.0.1:3306:3306 --name docker-mysql -v /Users/xxx/dev/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD="12345" mysql:5.7
|
mongo
容器文档
1
| docker run --name docker-mongo -v /Users/xxx/dev/docker/mongo/db:/data/db -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD="12345" -d mongo
|
进入命令行
1
| docker exec -it docker-mongo mongo -u "root" -p "12345" --authenticationDatabase "admin"
|
kafka
容器文档
参考
1、注意 KAFKA_ADVERTISED_HOST_NAME 要设置成本地IP 非localhost。
这里写了个脚本,每次动态获取本机IP,再创建容器运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| // get current ip
const os = require('os');
const interfaces = os.networkInterfaces();
const ips = [];
for (let key in interfaces) {
interfaces[key].forEach(function(details) {
if (details.family === 'IPv4' && !details.internal) {
ips.push(details.address);
}
});
}
if (ips.length === 0) {
throw Error('Get IP Failed!')
}
const chooseIp = ips[0];
console.log(`Current IP: ${ips}, Choose ${chooseIp}`);
// refresh config file
const fs = require('fs');
const REGEX = /\s?KAFKA_ADVERTISED_HOST_NAME/;
const readLines = [];
const configFile = '/Users/xxx/dev/docker/kafka/kafka-docker/docker-compose.yml';
fs.readFileSync(configFile, {encoding:'utf-8'})
.split(/\r?\n/)
.forEach(function (line) {
let matches = REGEX.exec(line);
if (matches) {
readLines.push(`${line.split(':')[0]}: ${chooseIp}`);
} else {
readLines.push(line);
}
});
fs.writeFileSync(`${configFile}`, readLines.join('\n'));
// restart docker container
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function run() {
const config = await exec('cat /Users/xxx/dev/docker/kafka/kafka-docker/docker-compose.yml;');
console.log(config.stdout);
const a = await exec('docker ps -a');
console.log(a.stdout);
await exec('cd /Users/xxx/dev/docker/kafka/kafka-docker; docker-compose stop; docker rm kafka-docker_zookeeper_1; docker rm kafka-docker_kafka_1;');
await exec('cd /Users/xxx/dev/docker/kafka/kafka-docker; docker-compose up -d;');
const b = await exec('docker ps -a');
console.log(b.stdout);
}
run()
|
2、常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 启动/停止/增加broker:参考容器文档
进入容器:
docker exec -it kafka-docker_kafka_1 /bin/bash
进入后创建topic:注意这里的ip要和docker-compose.yml里的KAFKA_ADVERTISED_HOST_NAME一致,即上面脚本获取的IP。
kafka-topics.sh --create --zookeeper 192.168.22.29:2181 --replication-factor 1 --partitions 1 --topic event_topic
查看topic:IP同上
kafka-topics.sh --list --zookeeper 192.168.22.29:2181
发送消息:IP同上 端口通过d.ps查看kafka的本地映射端口
kafka-console-producer.sh --broker-list 192.168.22.29:32771 --topic event_topic
读取消息:
kafka-console-consumer.sh --zookeeper 192.168.22.29:2181 --topic event_topic --from-beginning
|
redis
文档
1
2
3
4
5
| 创建容器:
docker run --name docker-redis -p 6379:6379 -d -v /Users/xxx/dev/docker/redis/data:/data redis
进入命令行:
docker exec -it docker-redis redis-cli
|
nginx
文档
1
2
3
4
5
6
7
| 创建容器:
docker run --name docker-nginx -p 80:80 -d \
-v /Users/xxx/dev/docker/nginx:/etc/nginx \
nginx
进入命令行:
docker exec -it docker-nginx /bin/bash
|
注意:docker里连接本机的localhost,要换成其他方式。
由于平时开发,nginx又要动态代理到本机localhost,所以任然保留了brew安装的版本 方便调试。
jenkins
文档
1
2
3
4
5
| docker pull jenkins/jenkins
docker run -d -p 8080:8080 -p 50000:50000 -v jenkins_home:~/dev/docker/jenkins --name jenkins jenkins/jenkins
docker exec -it jenkins /bin/sh
fedomn:fedomn-admin
|
golang
这里简单示例,将floating-ticket-server打包到docker中 方便部署使用。
1、要修改代码bind的IP从127.0.0.1到0.0.0.0。
原因,127是一个回环地址,表示“我自己”,不能通过外部访问,只能自己访问
0.0.0.0 不能ping通,代表本机所有的IPV4地址。
2、增加Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| FROM golang:latest AS build-env
ADD . /src
RUN cd /src && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app
FROM scratch
COPY --from=build-env /src/app /
COPY --from=build-env /src/key /
EXPOSE 12345
ENTRYPOINT ["/app"]
|
可以看出,分成两步骤。最后执行打包运行:
1
2
3
| docker build -t ticket .
docker run -d -p 12345:12345 --name ticket-server ticket
|
容器运行起来后,就可以通过外部localhost:12345进行访问了。
迁移注意
背景:
Mac time machine迁移后 images都丢失了
Mac docker版本 Version 18.03.1-ce-mac65 (24312)
分析:
Linux下容器在/var/lib/docker
下,而Mac下容器都在
/Users/xxx/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux
,主要都在Docker.qcow2里。
docker依赖Linux的cgroup,所以在mac上运行时候 会启动一个虚拟机中的Linux内核,同时 硬盘上存储一个qcow2格式的磁盘镜像文件。这个文件会随着Docker的使用不断膨胀,即使删除不用的Docker Image和Container也不会缩小。至少在这个版本官方还未解决。
网上有暴力的方法,先save image,再删除qcow2,最后load image。这种对于自己build的image可以使用。如果都是从官方hub里拉取的image,还是建议重新pull配置一下。毕竟也还是很简单的嘛,就是docker run一下。
坑:
time machine备份的时候 没有备份/Users/xxx/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux
这个目录。原因未知。
资料
DaoHub
官方Hub
Docker中文文档
Docker — 从入门到实践