docker-笔记

安装Docker-CE

https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11NLNZGM
https://developer.aliyun.com/article/110806

使用官方安装脚本自动安装 (仅适用于公网环境)
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

CentOS 7 (使用yum进行安装)
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安装 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
systemctl start docker 
# 查看docker版本
docker version
# 开机启动
systemctl enable docker

配置镜像

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
sudo systemctl daemon-reload
sudo systemctl restart docker

常用命令

docker ps // 查看运行的容器
docker ps -a  // 查看曾经运行过的容器
docker pull  // 从仓库拉取一个容器
docker images // 查看当前镜像
docker create nginx //创建一个容器 返回一个id
docker start xxx  // 启动
docker restart xxx  // 重新启动
docker run hello-world    // run 会尝试启动一个容器,没有会自动拉取镜像,创建并启动
-d 后台启动
-p 容器内端口映射到宿主机端口  宿主机端口:容器内端口
-c CPU份额
-v 目录映射 宿主机目录:容器内目录
-m 内存限制
--memory-swap 内存交换限制
--blkio-weight 	IO权重
--name 设置一个容器的名字
--restart=always 重启策略
no:不重启
on-failure:退出状态非0时重启
always:始终重启

docker pause 容器ID    // 暂停
docker unpause 容器ID  // 取消暂停
docker stop 容器ID     // 完全停止
docker rm 容器ID       //移除一个容器,不能移除正在运行的容器
docker rm -f 容器ID    // 强制移除一个容器
docker logs 容器ID     // 查看日志
docker logs -f 容器ID  //监听日志

# 和容器做交互 用bash方式
docker exec -it 容器ID /bin/bash

批量操作技巧

# 停用全部运行中的容器:
docker stop $(docker ps -q)
# 删除全部容器
docker rm $(docker ps -aq)
# 删除所有镜像
docker rmi docker images -q

# 按条件删除镜像
- 删除没有tag的镜像
docker rmi $(docker images -q | awk '/^<none>/ { print $3 }')
- 镜像名包含关键字 其中xxx为关键字
docker rmi --force $(docker images | grep xxx | awk '{print $3}')
# 重启那些意外退出的容器
docker restart $(docker ps -a|grep Exited|awk '{print $1}')

常用软件启动

# 启动redis 以服务方式启动
docker run -d --name myredis -p 6379:6379 redis redis-server
# 和容器做交互-it 用redis-cli
docker exec -it 1dad7fd6ffd5 redis-cli

# rabbitmq
docker run -d --name myrabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management

# mysql
docker run -d --name mymysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

# nginx 将前端代码映射到/usr/share/nginx/html
docker run -d --name myniginx -p 80:80 -v /frontcode:/usr/share/nginx/html nginx

# nginx 自定义配置
docker run \
-d \
-p 82:80 \
--restart=always \
-v ~/nginx/conf.d:/etc/nginx/conf.d \
-v ~/nginx/logs:/var/log/nginx \
nginx:1.21.6

# elk
docker pull sebp/elk
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -e ES_MIN_MEM=128m -e ES_MAX_MEM=1024m -d  --name elk sebp/elk

max_map_count问题以及解决
vim /etc/sysctl.conf
添加如下代码
vm.max_map_count=262144
-----
sysctl -p 
3. 进入docker容器:
docker exec -it 容器ID /bin/bash
4. 修改配置文件
配置文件的位置:/etc/logstash/conf.d/02-beats-input.conf
将其中的内容都删掉,替换成下面的配置
input {
    tcp {
        port => 5044
        codec => json_lines

    }

}
output{
    elasticsearch {
    hosts => ["localhost:9200"]

    }
}
5.	重启docker容器(大概等5-10分钟,等待服务重启)
docker restart elk
6. 访问Kibana
http://localhost:5601/

Dockerfile

Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。&& 符号连接命令,这样执行后,只会创建 1 层镜像.

vim Dockerfile 
---------------
#注释
# FROM 定制的镜像都是基于 FROM 的镜像
FROM debian
# RUN:用于执行后面跟着的命令行命令
# shell 格式:RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
# exec 格式 RUN ["可执行文件", "参数1", "参数2"]
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
RUN echo 'build start'
RUN mkdir software
# 复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY aa /software
# ADD相比CPOY,压缩文件会自动复制并解压到容器里指定路径
ADD bb.tar.gz .
# VOLUME 将容器产生的数据挂到宿主机上

# 类似于 RUN 指令, CMD 在docker run 时运行 RUN 是在 docker build
# CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖
# 注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
CMD ["-c","ls -l"]

# 类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
# 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
# ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
ENTRYPOINT ["/bin/sh"]

# 暴露一个端口
EXPOSE 8083
--------------------------
# 开始构建镜像 -t 指定一个名字 'name:tag' format
docker build -t demo .
docker run demo
# CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖
docker run demo -c date

docker compose

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.2.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

离线导入导出

# 使用 docker export 命令根据容器 ID 将镜像导出成一个文件。
docker export f299f501774c > images.tar
# 导入镜像
docker import - new_hangger_server < images.tar


# 使用 docker save 命令根据容器 ID 将镜像保存成一个文件。 这个方法导入得镜像没有名字和标签
docker save 0fdf2b4c26d3 > images.tar
# 同时保存多个
docker save -o images.tar postgres:9.6 mongo:3.4
# 载入镜像
docker load < images.tar

两种方案的差别

  • 两种方法不可混用。如果使用 import 导入 save 产生的文件,虽然导入不提示错误,但是启动容器时会提示失败,会出现类似"docker: Error response from daemon: Container command not found or does not exist"的错误。
  • export 导出的镜像文件体积小于 save 保存的镜像
  • docker import 可以为镜像指定新名称,docker load不能对载入的镜像重命名
  • export 不支持同时将多个镜像打包到一个文件中,save可以
  • export 导出是根据容器拿到的镜像,再导入时会丢失镜像所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以无法进行回滚操作。而 save 保存的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。
  • docker export 的应用场景:主要用来制作基础镜像,比如我们从一个 ubuntu 镜像启动一个容器,然后安装一些软件和进行一些设置后,使用 docker export 保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。
  • docker save 的应用场景:如果我们的应用是使用 docker-compose.yml 编排的多个镜像组合,但我们要部署的客户服务器并不能连外网。这时就可以使用 docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入。

离线安装Docker/Docker-Compose

https://download.docker.com/linux/static/stable/x86_64/
https://github.com/docker/compose/releases

  • docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
# ARM国产服务器需要修改成65535
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
  • install.sh
#!/bin/sh

# 安装docker
tar -xvf docker-20.10.14.tgz
cp docker/* /usr/bin/
cp docker.service /etc/systemd/system/
chmod +x /etc/systemd/system/docker.service
systemctl daemon-reload
systemctl start docker
cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
systemctl enable docker
systemctl daemon-reload
systemctl restart docker
docker -v
echo 'docker安装成功...'
cp docker-compose-linux-x86_64  /usr/bin/docker-compose
chmod +x  /usr/bin/docker-compose
docker-compose -v
echo 'docker-compose安装成功...'
  • uninstall.sh
#!/bin/sh
echo '删除docker.service...'
rm -f /etc/systemd/system/docker.service
echo '删除docker文件...'
rm -rf /usr/bin/docker*
echo '重新加载配置文件'
systemctl daemon-reload
echo '卸载成功...'

遇到的问题

  1. docker运行容器报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
#在宿主机上执行
echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
#重启network和docker服务
systemctl restart network && systemctl restart docker
  1. 以root权限进入Docker容器
# 首先在启用Docker容器的时候,必须加上--privileged=true。例:
`docker run -d -p 8888:8888 --privileged=true xxx`
# 在进入容器时,使用:
docker exec -it -u root [ContainerID] /bin/bash
# 此时你已经以root身份进入docker容器了 ,就算使用su也不需要输入密码。
  1. 非root用户使用docker
# gitlab-runner用户添加到docker组
sudo usermod -aG docker gitlab-runner
  1. library initialization failed - unable to allocate file descriptor table - out of memory在一些比较老的机器或者是ARM内核的国产服务器上容易出现
(1) LimitNOFILE=infinity 虽然是不限制,但是在systemctl版本小于234的时候不生效,查看systemctl版本:systemctl --version

(2) docker容器的ulimit太小了,有文档说太大也不行

3.解决方法

#修改/lib/systemd/system/docker.service文件

LimitCORE=infinity
LimitNOFILE=infinity
LimitNPROC=infinity

改成

LimitCORE=65535
LimitNOFILE=65535
LimitNPROC=65535

#重启docker服务

docker -mysql 导入导出

# 查找mysql 容器ID
docker ps
# 进入mysql容器
docker exec -it 708927398ed3 bash
# 导出数据库 输入mysql密码 
mysqldump -u root -p 123456 > dump.sql
# pwd 记住导出文件地址
pwd
# 退出容器
exit
# 把容器中dump.sql文件拷贝到本机
docker cp 708927398ed3:dump.sql ~/
# 把本地文件复制进容器
docker cp /home/change20231229.sql  容器ID:/change20231229.sql
# 进入mysql容器
docker exec -it 容器ID bash
#导入
mysql -u root -p123456 --default-character-set=utf8 dbname < change20231229.sql

快速打包脚本

#!/bin/bash

declare -A map

# 定义保存镜像的目录
save_dir="/vagrant/images"

# 确保保存目录存在
mkdir -p "$save_dir"

# 定义镜像数组
images=(
  "xxx:202408131631"
)



# 拉取并保存每个镜像
for image in "${images[@]}"
do
  # 去除前缀并替换冒号为下划线
  filename=$(echo "$image" | sed 's/swr.cn-north-4.myhuaweicloud.com\/xiaoshou\///' | sed 's/:/-/g' | sed 's/$/.tar/')
  save_path="${save_dir}/${filename}"
  echo "Pulling and saving image: $image as $save_path"
  
  # 拉取镜像
  docker pull "$image"
  
  # 保存镜像到tar文件
  docker save "$image" -o "$save_path"
  echo "Image saved as $save_path"
done

echo "All images have been pulled and saved."
posted @ 2022-01-24 17:23  Ranger-dev  阅读(120)  评论(0编辑  收藏  举报