Docker
Dockerfile
构建镜像
javascript
const http = require('http');
const os = require('os');
console.log("Kubia server starting ...");
var handler = function(request, response) {
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
}
var www = http.createServer(handler);
www.listen(8080);
// 构建 nodejs 项目用于容器部署编写 Dockerfile
dockerfile
FROM node:7 # 基于什么镜像制作
ADD app.js /app.js # 将当前目录下的 app.js 移到容器根目录
ENTRYPOINT ["node", "app.js"] # 启动容器时的执行命令镜像打包
shell
docker build -t ${name} .进入容器内部
shell
docker exec -it ${docker_name} bash
-i表示标准输入流保持开放-t用于分配一个伪终端
Docker 镜像推送
shell
# 将本地镜像加自己账户名前缀的 tag
docker tag ${local_image} ${your_account_name}/${remote_image}
docker tag busybox xiaokexiang/busybox
# docker 账户登录
docker login
# 推送到远端
docker push xiaokexiang/busybox命令对比
ADD & COPY
两者都可以将宿主机的文件复制到容器内,ADD 具备自动解压的功能,而 COPY 只是复制功能。
dockerfile
FROM busybox
ADD hello.tar /
COPY hello.tar /
- 使用 ADD 命令,镜像 build 后,在
/目录下就会存在解压后的文件(不会存在压缩包!)- 使用 COPY 命令,镜像 build 后,在
/目录下会存在压缩包
CMD & ENTRYPOINT
两者都用于指定容器启动程序及参数,当存在 ENTRYPOINT 时,CMD 的内容会作为参数传递给 ENTRYPOINT。 需要注意的是:我们执行 docker run busybox echo hello 指令中的 echo hello 就是 CMD 命令(默认覆盖 Dockerfile 中的 CMD 命令),只是它没有写在了 Dockerfile 中,而是显示的传入。
dockerfile
FROM busybox
CMD ["ls", "-l"]
# ENTRYPOINT ["ls", "-l"]
- 镜像 build 后,若执行
docker run image -h,那么会提示错误信息(因为覆盖了ls -l命令,执行的是-h)。而将 CMD 换成 ENTRYPOINT 则不会(会拼接,执行ls -l -h)。
ENV & ARG
两者都用于设置环境变量,区别在于 ENV 无论是镜像构建时还是容器运行时,都可以使用。ARG 只是用于构建镜像时使用,容器运行时不会出现。
dockerfile
FROM busybox
ENV NAME="helloworld"
WORKDIR /
RUN touch $NAME # 构建镜像时使用变量
CMD ["sh", "-c", "echo $NAME && ls"]
- 如果此处不使用
sh -c执行命令,那么并不会正确显示 ENV 变量- 如果在一行中执行多个命令,需要使用
-c显示指定
tini
tini(Tiny Init 的缩写)是一个轻量级的初始化系统,用于解决在容器环境中启动进程时可能遇到的一些问题。它设计用于替代传统的 init 系统,如 systemd 或 sysvinit,以提供更好的容器进程管理。
- 一般来说,docker 容器启动时,容器内第一个启动的进程会被分配为 PID1,通常 PID1 的进程被视为 init 进程,init 进程负责启动和管理其他系统进程
- 当 java 进程成为 PID1 时,会出现 JVM 无法正确处理 SIGTERM 信号来优雅的终止进程。
jstack <pid>命令也无法处理,因为无法处理SIGQUIT信号- tini 被设计为更好地处理信号,并能够确保它们正确地传递给 Java 进程,以便在容器停止时进行优雅的关闭
dockerfile
FROM busybox
RUN wget -O /sbin/tini https://github.com/krallin/tini/releases/download/v0.19.0/tini-static-amd64
RUN chmod +x /sbin/tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["sleep", "infinity"]top 查看 pid,tini 进程的 pid 为 1
Docker Command
MySQL
不挂载启动
shell
# 不使用挂载创建 mysql
docker run -itd -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql5.7 mysql:5.7挂载宿主机目录启动
shell
# 创建宿主机目录
mkdir -p /opt/mysql/{logs,conf.d,data}
# 拷贝默认配置文件到宿主机(借助上文的不挂载启动的 mysql 容器)
docker cp mysql:/etc/mysql/conf.d/. /opt/mysql/conf.d
docker cp mysql:/var/log/mysql/. /opt/mysql/logs
# 可以不拷贝自己创建配置文件
touch /opt/mysql/conf.d/my.cnf
# 执行挂载命令并启动
docker run -p 3306:3306 --name mysql \
-v /opt/mysql/conf.d:/etc/mysql/conf.d \
-v /opt/mysql/logs:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7
mysql 5.7 或 8.0 版本都可以使用该命令。
MySQL 相关命令
shell
# 进入 mysql 控制台 root/123456,指定端口 3316 和 host 127.0.0.1
mysql -uroot -P 3316 -h 127.0.0.1 -p123456
# 创建远程用户 test/abcdefg
CREATE USER 'test'@'%' IDENTIFIED WITH mysql_native_password BY 'abcdefg';
GRANT ALL PRIVILEGES ON *.* TO 'test'@'%';
# 查看数据库,表,使用数据库
show databases;
use mysql;
show tables;
# 控制台内执行本地的 sql 文件
source /root/select.sql
# 控制台外备份数据库
mysqldump -u root -P 3316 -p dbname > /root/backup.sqlNginx
不挂载启动
shell
docker run -itd --name nginx -p 80:80 -p 443:443 nginx拷贝 Nginx 默认配置文件
shell
# 将容器内的 conf.d 文件夹下的所有文件复制到宿主机上/opt/nginx/conf.d 文件夹下
docker cp nginx:/etc/nginx/conf.d/. /opt/nginx/conf.d
# 将容器内的 conf.d 文件夹(包含文件夹内的文件)复制到宿主机上/opt/nginx 目录下
docker cp nginx:/etc/nginx/conf.d /opt/nginx/挂载宿主机目录启动
shell
# 创建宿主机目录
mkdir -p /opt/nginx/{logs,conf.d,html}
# 拷贝默认配置文件到宿主机(借助上文的不挂载启动的 nginx 容器)
docker cp nginx:/etc/nginx/conf.d/. /opt/nginx/conf.d
docker cp nginx:/usr/share/nginx/html/. /opt/nginx/html
# 执行挂载命令并启动
docker run -it --name nginx \
-v /opt/nginx/html:/usr/share/nginx/html \
-v /opt/nginx/logs:/var/log/nginx \
-v /opt/nginx/conf.d:/etc/nginx/conf.d \
-p 80:80 -p 443:443 \
-d nginxnginx 的配置文件可以通过
nginx -t来进行校验。
Kafka
bash
# zookeeper
docker run -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper
# kafka
docker run -d --rm --name kafka_2.21 -p 9092:9092 \
-e KAFKA_BROKER_ID=1 \
-e ALLOW_PLAINTEXT_LISTENER=yes \
-e KAFKA_CFG_ZOOKEEPER_CONNECT=10.50.8.23:2181 \
-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://10.50.8.23:9092 \
-e TZ="Asia/Shanghai" \
bitnami/kafka:2.2.1
# kafdrop
docker run -d --rm --name kafdrop -p 9009:9000 \
-e KAFKA_BROKERCONNECT=10.50.8.23:9092 \
-e JVM_OPTS="-Xms32M -Xmx64M" \
-e SERVER_SERVLET_CONTEXTPATH="/" \
obsidiandynamics/kafdrop多平台镜像构建
利用 Docker 的 buildx 插件实现多平台结构镜像的构建,使用前提:内核版本 >= 4.8 & docker >= 19.03。
定义构建器配置
bash
cat <<EOF > config.toml
[registry."docker.io"] # 配置 docker.io 的镜像代理
mirrors = ["hub-mirrors.c.163.com"]
[registry."abcsys.cn:5000"] # 配置自定义仓库的代理、支持 insecure 推送(私有仓库必备)
mirrors = ["abcsys.cn:5000"]
http = true
insecure = true
[registry."jenkins.oem"]
mirrors = ["jenkins.oem"]
http = true
insecure = true
EOF创建构建器
bash
# 查看已经存在的构建器
docker buildx ls
# 删除构建器
docker buildx rm -f custom-builder
# 创建构建器(会同步基于 moby/buildkit 的容器镜像),并将宿主机的 host 映射到这个容器中(私有仓库必备)
docker buildx create --use --name custom-builder --config=./config.toml --driver-opt network=host --buildkitd-flags '--allow-insecure-entitlement network.host'
# 将 custom-builder 作为默认构建器
docker buildx use custom-builder
# 启动构建器
docker buildx inspect --bootstrap custom-builder构建多架构镜像
基于下面的命令创建所需文件:
bash
# Dockerfile
cat <<EOF > Dockerfile
# 定义相关文件,用于展示容器所在系统的架构
FROM golang AS builder
WORKDIR /app
ADD . .
RUN go build -o hello .
FROM alpine
WORKDIR /app
COPY --from=builder /app/hello .
CMD ["./hello"]
EOF
# main.go
cat <<EOF > main.go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Printf("Hello, %s/%s!\n", runtime.GOOS, runtime.GOARCH)
}
EOF
# go.mod
cat <<EOF > go.mod
module hello
go 1.20
EOF构建 amd64 和 arm64 双架构镜像:
bash
# 构建 amd 和 arm 架构镜像并推送,因为默认是构建在缓存中的
docker buildx build --platform linux/arm64,linux/amd64 -t abcsys.cn:5000/public/hello-go . --push查看远程仓库的镜像 manifest 信息:
bash
docker buildx imagetools inspect abcsys.cn:5000/public/hello-go
# Name: abcsys.cn:5000/public/hello-go:latest
# MediaType: application/vnd.docker.distribution.manifest.list.v2+json
# Digest: sha256:faf291d4054f0e1958b77fc45786e18725e0180bf67a801dc1e1531dab430c0a
#
# Manifests:
# Name: abcsys.cn:5000/public/hello-go:latest@sha256:893411d11003ed93665b2c383400600d0bf0ea40c29f23e958d8932d3b3b4b89
# MediaType: application/vnd.docker.distribution.manifest.v2+json
# Platform: linux/arm64
#
# Name: abcsys.cn:5000/public/hello-go:latest@sha256:860abc41643953f466ccc3c38fc4b927793039b188dcc9882794ac58583474e2
# MediaType: application/vnd.docker.distribution.manifest.v2+json
# Platform: linux/amd64
🎈🎈