docker
一、物理机/虚拟机准备
[!tip] > docker-ce 需要内核3.10以上版本,所以centos7的版本要尽量新,否则容易安装不成功
- 克隆虚拟机模板, 设置IP为192.168.20.150,虚拟机安装之克隆安装
# 一、克隆安装
- 选择已经准备好并关机的模板服务器170,右键进行克隆
- 执行脚本配置ip、主机名
- vcenter控制可考虑用图形化工具进行配置和激活, ==nmtui== , 设置ip网关及主机名
hostnamectl set-hostname test1.dev.lzh
bash
sed -i 's/192.168.20.170/192.168.20.161/' /etc/sysconfig/network-scripts/ifcfg-ens192
systemctl restart network
ip a s
hostname -s
hostname -f
ip r
- 安装后测试是否可远程连接,ok后关机
- 关闭防火墙及安全设置(全新安装才需要,模板已统一设置,故可以跳过)
#----------------------------------------------------------
# 建议关闭的初始化操作
#----------------------------------------------------------
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭Selinux
setenforce 0
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 关闭SWAP
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab
# 设置主机名
hostnamectl set-hostname template
bash
二、Docker 环境安装
- 设置阿里云的源,安装docker-ce
cd /etc/yum.repos.d/
rename .repo .repobak ./*
wget -O /etc/yum.repos.d/aliyun-centos7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/aliyun-centos-docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all
yum makecache fast
yum update -y
yum repolist
yum install -y yum-utils device-mapper-persistent-data lvm2
yum install -y docker-ce
- 关闭防火墙、开机自启docker,并设置阿里云加速源,需登录阿里云容器镜像服务 (aliyun.com)
systemctl stop firewalld
systemctl disable firewalld
systemctl enable docker
systemctl start docker
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://6yga1re5.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
docker --version
- docker hello world (注:run模式下,执行即结束,后端遗留垃圾容器)
docker run ubuntu:16.04 /bin/echo "Hello world"
# 进入容器内,退出容器消亡,但还遗留
docker run -it ubuntu:16.04 /bin/bash
三、Docker日常维护
2.1、镜像操作
- dockerHub镜像操作
# web查询,访问 https://hub.docker.com
# 拉取最新镜像, 不写tag,默认拉取latest
docker pull nginx
# 查看latest实际版本
docker image inspect nginx:latest | grep -i version
# 拉取指定版本,建议去hub的tags标签页查找
docker pull nginx:1.20
# 删除dangling 悬挂镜像
docker rmi $(docker images -f "dangling=true" -q)
- 本地镜像操作
# 查看本地镜像清单
docker images
# 导出镜像为tar
docker save -o nginx.tar nginx:latest
# 删除镜像, 无标记,默认删除lastest
docker rmi nginx
# 导入镜像
docker load -i nginx.tar
# tag标记或备份?
docker tag nginx:latest nginx:lin
2.2、容器操作
- dockerHub镜像操作
# 运行一个容器,并设置名称、端口【宿主机:容器端口】、后端运行、镜像:版本号
docker run --name mn -p 80:80 -d nginx:latest
# 查看运行或暂挂的容器, -a 可看到停止的容器
docker ps
# 查看容器日志
docker logs mn
# 进入容器bash, 退出直接exit
docker exec -it mn bash
# 不进入容器,直接修改容器内文件
docker exec -it mn \
sed -i 's#Welcome to nginx#lin baba welcome#g' \
/usr/share/nginx/html/index.html
# 暂停、恢复容器
docker pause mn
docker unpause mn
# 停止并删除容器
docker stop mn
docker ps -a
docker rm mn
# 日志驱动??
docker run -d \
– log-driver=fluentd \
– log-opt fluentd-address=10.2.3.4:24224 \
– log-opt tag=”docker.{{.Name}}” \
nginx
2.3、数据卷及目录挂载
- 数据卷挂载实验, 宿主机本地默认目录
# 创建数据卷、检阅、prune无使用删除方式
docker volume create html
docker volume inspect html
docker inspect html
docker volume prune -f
# 再次创建数据卷,运行nginx容器并关联
docker volume create html
docker inspect html
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
docker ps
curl localhost
# 测试容器被删除后,数据卷内文件保存, 因此也证明了卷内的文件是从只读的容器拷贝过来的!而非简单链接使用
docker rm -f mn
ls -l /var/lib/docker/volumes/html/_data
sed -i 's#Welcome to nginx#lin baba welcome#g' \
/var/lib/docker/volumes/html/_data/index.html
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
# 删除容器、删除卷、重新运行容器并标识数据卷,自动创建数据卷!
docker rm -f mn
docker ps -a
docker volume ls
docker volume prune
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
- 目录挂载,更灵活
docker pull mysql:5.7.37
mkdir -p /tmp/mysql/{conf,data}
tee /tmp/mysql/conf/hmy.cnf <<-'EOF'
[mysqld]
skip-name-resolve
character_set_server=utf8
datadir=/var/lib/mysql
server-id=1000
EOF
docker run \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
-v /tmp/mysql/data:/var/lib/mysql \
-d mysql:5.7.37
四、网络
五、dockerFile定制镜像
# prepare
docker pull nginx:stable
mkdir -p /usr/local/docker/nginx_docker/html
cd /usr/local/docker/nginx_docker/
echo "<center>hello linbaba</center>" > /usr/local/docker/nginx_docker/html/index.html
tee Dockerfile <<-'EOF'
FROM nginx:stable
MAINTAINER linzhihui <linzhihui@hotmail.com>
COPY ./html/index.html /usr/share/nginx/html
EOF
docker build -t mynginx:v1.0.1 .
docker tag mynginx:v1.0.1 mynginx:latest
docker run -it --rm --name web\
-p 8081:80 \
-d mynginx:latest
docker stop web
六、dockerCompose使用
- 安装道客镜像的docker-compose,DaoCloud/docker-mirror: docker hub mirror, Docker镜像加速器 (github.com)
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
- 测试,py+redis的compose组合
mkdir /tmp/composetest && cd /tmp/composetest
tee /tmp/composetest/app.py <<-'EOF'
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
EOF
tee /tmp/composetest/requirements.txt <<-'EOF'
flask
redis
EOF
tee /tmp/composetest/Dockerfile <<-'EOF'
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
EOF
tee /tmp/composetest/docker-compose.yml <<-'EOF'
# yaml 配置
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
EOF
docker-compose up -d
docker-compose down
七、Docker 仓库
7.1、registry
7.2、habor
- docker的仓库是默认registry,vm家的habor功能更强大和主流
- gg搜索gohabor,从官网进入github下载离线tgz包
7.2.1、Habor安装配置
tar zxvf harbor-offline-installer-v2.5.0.tgz -C /usr/local/
/usr/local/harbor/
cp harbor.yml.tmpl harbor.yml
# 修改hostname和端口,并注释掉https和证书
./install.sh
# web访问 admin/Harbor12345, 修改密码,添加项目repo公开仓库
7.2.2、linux/docker宿主机上传、下载测试
tee /etc/docker/daemon.json <<-'EOF'
{
"insecure-registries": ["192.168.20.151:80"]
}
EOF
systemctl restart docker
cd /usr/local/harbor
docker-compose up -d
docker tag demo:v1.0.0 192.168.20.151:80/repo/demo:v1.0.0
docker login -u admin -p Harbor12345 192.168.20.151:80
docker push 192.168.20.151:80/repo/demo:v1.0.0
# 删除本地,再从网络拉取
docker rmi 0ace52fd71b4 -f
docker pull 192.168.20.151:80/repo/demo:v1.0.0
7.2.3、整合jenkins-整合宿主机docker、打包上传镜像
cd /var/run/
chown root:root docker.sock
chmod o+rw docker.sock
# 修改compose文件,增加3个docker文件支持,方便使用宿主机进行docker镜像打包
cd /usr/local/docker/jenkins_docker
tee docker-compose.yml <<-'EOF'
version: '3.1'
services:
jenkins:
image: 'jenkins/jenkins:2.319.1-lts'
container_name: jenkins
ports:
- '8080:8080'
- '50000:50000'
volumes:
- './data:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
- '/usr/bin/docker:/usr/bin/docker'
- '/etc/docker/daemon.json:/etc/docker/daemon.json'
EOF
docker-compose up -d
docker exec -it jenkins bash
# 检查docker是否整合成功
docker version
# 可以去除构建后操作和compose文件,在构建成功后,添加以下shell
mv target/*.jar docker/
docker build -t mytest:$demoProjectTag docker/
docker login -u admin -p Harbor12345 192.168.20.151:80
docker tag mytest:$demoProjectTag 192.168.20.151:80/repo/mytest:$demoProjectTag
docker push 192.168.20.151:80/repo/mytest:$demoProjectTag
7.2.4、整合jenkins-通知、下载镜像
- 准备shell脚本,并手工测试
mkdir /usr/local/test
cd /usr/local/test
tee deploy.sh <<-'EOF'
#!/bin/bash
harbor_addr=$1
harbor_repo=$2
project=$3
version=$4
host_port=$5
container_port=$6
imageName=$harbor_addr/$harbor_repo/$project:$version
echo $imageName
containerId=`docker ps -a|grep ${project} | awk '{print $1}'`
echo $containerId
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
fi
tag=`docker images |grep ${project} | awk '{print $2}'`
if [[ "$tag" =~ "$version" ]] ; then
docker rmi $imageName
fi
docker login -u admin -p Harbor12345 $harbor_addr
docker pull $imageName
docker run -d -p $host_port:$container_port --name $project $imageName
echo "SUCCESS"
EOF
chmod +x deploy.sh
./deploy.sh 192.168.20.151:80 repo demo v2.0.0 8081 8080
- 整合jenkins, 添加构造后的操作、端口参数,便于日常调整
/usr/local/test/deploy.sh 192.168.20.151:80 repo demo $demoProjectTag $host_port $container_port
7.2.5、整合jenkins-发送webhook到dingtalk/微信
- 企业微信
- 先拉两人建群聊,添加机器人,获得webhook地址,及使用帮助
- jenkins 安装qy wechat插件
- 在构建后添加企业微信通知接口,pipeline方式下面有,比较麻烦
- 钉钉
- 基本类似企业微信,pipiline效果看上去还可以,具体未尝试,可参考哔哩哔哩_bilibili
- 微信
- 无webhook接口,不过可借助第三方,搜索pushplus
八、dockerSwarm
1
九、有趣的应用
9.1、时区设置
- alpine时区设置(现成镜像)
- 注:查看是哪个发行版本
cat /etc/issue
- 注:查看是哪个发行版本
# 进入镜像,设置阿里源,安装tzdata,设置本地时间和时区,然后清理tzdata
docker exec -it demo2 sh
echo -e "http://mirrors.aliyun.com/alpine/v3.4/main\nhttp://mirrors.aliyun.com/alpine/v3.4/community" \
> /etc/apk/repositories && apk update
apk add tzdata
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
apk del tzdata
# 检查,看时间是不是从+0到+8
date -R
- alpine时区设置(dockerFile)
# dockerfile文件中填入这段
# alpine基础镜像修改默认时区为上海
RUN echo -e "http://mirrors.aliyun.com/alpine/v3.4/main\nhttp://mirrors.aliyun.com/alpine/v3.4/community" > /etc/apk/repositories \
&& apk update && apk add tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Shanghai/Asia" > /etc/timezone \
&& apk del tzdata
- debian时区设置(dockerFile)
# dockerfile文件中填入这段
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*
- debian时区设置(现成镜像)
ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo Asia/Shanghai > /etc/timezone
dpkg-reconfigure --frontend noninteractive tzdata
rm -rf /var/lib/apt/lists/*
- debian时区设置(容器启动或创建时指定参数)
# -e TZ=Asia/Shanghai
docker run -e TZ=Asia/Shanghai -p 8081:8080 --rm -d --name demo2 demo:1.0
- busybox-helloworld
yum install glibc-static -f
mkdir -p /tmp/busybox && cd /tmp/busybox
tee /tmp/busybox/hello.c <<-'EOF'
#include <stdio.h>
int main(){
printf("hello busybox\n");
}
EOF
gcc hello.c -static -o hello
tee /tmp/busybox/Dockerfile <<-'EOF'
FROM busybox
ADD hello /
CMD ["/hello"]
EOF
docker build -t myhello .
docker images
docker run --name myhello -d myhello
docker logs myhello
- 指定jdk的最小基础镜像
docker pull jeanblanchard/busybox-java
- java demo
tee /tmp/busybox/Dockerfile <<-'EOF'
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk1.8.0_144 $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
&& ln -s ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
EOF
docker rm -f javaweb \
&& docker build -t javaweb:1.3 . \
&& docker tag javaweb:1.3 javaweb:latest
docker run --name javaweb -p 8090:8090 -d javaweb
- 轻量级jdk,相比ubuntu,从537MB降到171,少了366MB
tee /tmp/busybox/Dockerfile <<-'EOF'
# 指定基础镜像
FROM java:8-alpine
# 拷贝java项目的包
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
EOF
docker rm -f javaweb \
&& docker build -t javaweb:2.0 . \
&& docker tag javaweb:2.0 javaweb:latest
docker run --name javaweb -p 8090:8090 -d javaweb
评论系统未开启,无法评论!