老男孩docker入门基础

本篇文章是我之前通过学习老男孩k8s系列视频教程整理出来的笔记,为了便于自己之后的学习和巩固将它发表出来。

Docker学习目录:

对于容器一般的定义:

容器之间是互相隔离的,但是会共享操作系统和需要的二进制bin和库文件lib。

docker通过AUFS技术挂载。

13年,还没有分企业版和社区版。17年开始分企业版和社区版。
2:1.13.1-102.git7f2769b.el7.centos 是指 1.13.1 -- 13年

Docker容器引擎安装部署配置

安装yum-utils:

yum install yum-utils -y

安装epel源:

yum install epel-release –y

查看docker有关的包:

yum list docker --show-duplicates 

阿里源docker-ce的源:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

列出现在docker-ce的源,出现了新版本:

yum list docker-ce --show-duplicates 

安装docker-ce ,安装的是最新版:

yum install docker-ce –y
systemctl start docker
systemctl enable docker
docker info

对docker容器引擎做配置:

vim /etc/docker/daemon.json
{
  "graph": "/data/docker",
  "storage-driver": "overlay2",
  "insecure-registries": ["registry.access.redhat.com","quay.io"],
  "bip": "172.17.0.1/24",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "live-restore": true
}

解释:

  • Graph :docker工作目录
  • Storage-driver:overlay2 的存储驱动
  • Insecure:私有的仓库 两个,registry阿里源镜像加速器和quay
  • Bip:docker网络,需要和主机后两位相同,方便定位问题。
  • Exec-opts:启动时额外的参数,cgroupdriver是systemd形式
  • Live-restore:不依赖docker引擎的状态。

重启docker:

systemctl restart docker

查看docker信息:

Docker info/docker version

有的配置是我们在daemon.json中定义的

Docker run hello-word	(docker官方镜像)

  • 1.本地找不到hello-world镜像
  • 2.拉镜像,去下载,完成了 hello-world:latest

容器是怎么跑起来的?

Following steps:
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

步骤是:

  • 1.docker客户端连接到服务端,docker是C/S架构的软件
  • 2.从docker hub上拉取了hello-world镜像
  • 3.Docker服务端创建了一个新容器,是从拉取镜像启动的,并执行了一段脚本,生成了一段信息。
  • 4.Docker把信息流返回到客户端,并展示到终端上

Docker3个非常重要的概念:容器,镜像,仓库。

本地和远端是逻辑上的概念

解释:

  • 1.Registry_name:远端仓库的地址 URL
  • 2.Repository_name:分级仓库名
  • 3.Image_name:镜像名(最后一级仓库)
  • 4.Tag_name:标签名/镜像版本号

Dockerhub的账号:https://hub.docker.com/,类似于github
免费的必须是公开的,如果要设置为私人的,那需要转账付费。

Docker 仓库

登录:

docker login docker.io
用户名:zhangyiwen0724
密码:12345677654321

登录认证信息在:cat /root/.docker/config.json

Auth后面的信息是base64的编码:

echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"|base64 –d

搜索一个镜像:

docker search alpine

也可以在dockerhub官网搜索镜像

下载镜像:

docker pull alpine 默认下载latest

指定tag:

docker pull alpine:3.14

或使用这个命令:

docker pull docker.io/library/alpine:3.13.1

查看本地镜像:

docker images

image id相同,说明是同一个镜像。所以latest是一个指针,指向最新的镜像。

给镜像打标签:

docker tag d4ff818577bc docker.io/zhangyiwen0724/alpine:v3.14

推送镜像:

docker push docker.io/zhangyiwen0724/alpine:v3.14

打标签:

docker tag d4ff818577bc zhangyiwen0724/alpine:latest

再次推送:

docker push docker.io/zhangyiwen0724/alpine:latest

上面两个指向的是同一个镜像
拉和推,默认走https协议,自己建的仓库,默认走http,设置了证书,也是https。

删除镜像:

docker rmi docker.io/zhangyiwen0724/alpine:latest

(只是把标签去除了 镜像还在)

彻底删除 + image id:

docker rmi d4ff818577bc  删除会提示其他镜像在使用
docker rmi –f d4ff818577bc 彻底删除

docker hub上还是有的,本地再有。

docker pull zhangyiwen0724/alpine

总结:

可写的层才叫容器层,除最上层都是只读的。
Base image部分只是第一次启动慢,后面启动都是在增量基础上起的。只要增量小启动就会快。启动的快慢与绝对大小无关,与增量大小有关。

基本操作

查看本地的容器进程

docker ps
docker ps –a

docker.io/library/hello-world:latest

启动容器:

docker run -ti zhangyiwen0724/alpine:latest /bin/sh  

cat /etc/issue

非交互式启动一个容器:

docker run --rm zhangyiwen0724/alpine:latest /bin/echo hello

一次性的运行容器 加了rm 运行完指定的命令后,容器会自己退出。

docker images是看不到刚启动的容器的

非交互式的启动一个后台容器:
加了-d

docker run -d --name myalpine zhangyiwen0724/alpine:latest /bin/sleep 300

查看容器:

docker ps / docker ps -a

宿主机上也可以查到这个进程:

ps aux | grep sleep | grep -v grep

进入容器:

docker –exec -ti d5519da02daa /bin/sh

停止容器:

docker stop d5519da02daa

开启上面停止的容器:

docker start d5519da02daa

docker restart d5519da02daa
restart---stop--->start

或使用容器名字

docker restart myalpine

删除容器:

名字/image id
docker rm boring_cannon
docker rm ef5fd9422766

正在运行的容器 删除需要加-f:

docker rm -f myalpine

删除所有exit的容器:

for循环:
for i in `docker ps -a|grep -i exit|awk '{print $1}'`;do docker rm -f $i;done

启动容器myalpine:

docker run -d --name myalpine zhangyiwen0724/alpine:latest /bin/sleep 300

进入上面启动的容器:

docker exec -it myalpine /bin/sh

txt只在容器可写层,过了300s后就不在了。
提交到可写层,给一个新的镜像名字:

docker commit -p myalpine zhangyiwen0724/alpine:v3.13_with_1.txt

出现了新的镜像:

把1.txt固化到只读层。

用新镜像启动新容器:

docker run -ti zhangyiwen0724/alpine:v3.13_with_1.txt /bin/sh

只有commit才能修改镜像中的内容

或者使用export命令:

停止所有exit的容器:-I 忽略大小写

for i in `docker ps -a|grep -i exit|awk '{print $1}'`;do docker rm -f $i;done

导出/导入镜像

导出镜像:

docker save 36310fbabf04 > alpine:v3.13_with_1.txt.tar

导入镜像:

docker load < alpine:v3.13_with_1.txt.tar

没有标签,设置标签

docker tag  36310fbabf04 zhangyiwen0724/alpine:v3.13.1_with_1.txt

docker run --rm -ti --name myalpine_with_1.txt zhangyiwen0724/alpine:v3.13.1_with_1.txt /bin/sh

查看容器的日志:

docker run hello-world 2>&1 >> /dev/null

不在当前终端上输出信息,不加后面的直接打印到终端,

docker logs 1753da96bd3a

查看本来应该在终端的输出,输出到日志里了

docker logs -f 1753da96bd3a –f 动态输出

高级操作(不复杂,高级是很重要)

下载nginx镜像:

docker pull nginx:1.12.2
docker tag 4037a5562b03 zhangyiwen0724/nginx:v1.12.2

运行,并暴露80端口:

docker run --rm --name mynginx -d -p81:80 zhangyiwen0724/nginx:v1.12.2
宿主机端口:容器内端口

查看启动的nginx容器:

挂载数据卷:

mkdir html
cd html
wget www.baidu.com –O index.html
cat index.html

docker run -d --rm --name nginx_with_baidu -d -p82:80 -v/root/html:/usr/share/nginx/html zhangyiwen0724/nginx:v1.12.2
docker ps –a 访问宿主机+82端口,访问的是百度主页

使用/bin/bash进入容器:

docker exec -ti nginx_with_baidu /bin/bash 

docker inspect a8a246374141
docker inspect a8a246374141 | grep share

传递环境变量:

云原生,接受宿主机传递的环境变量:

docker run --rm -e E_OPTS=abcdefg zhangyiwen0724/alpine:latest printenv

E_OPTS=abcdefg 定义的环境变量的键值对
Printenv 打印出所有的环境变量

不加-e 就不会打印定义的环境变量

也可以传递多个环境变量:

docker run --rm -e E_OPTS=abcdefg -e C_OPTS=123456 zhangyiwen0724/alpine:latest printenv

容器内的安装工具,取决于是什么发行版
容器内安装软件:

docker exec -ti nginx_with_baidu /bin/bash

装curl命令

更新apt源:

root@a8a246374141:/# tee /etc/apt/sources.list << EOF
> deb http://mirrors.163.com/debian/ jessie main non-free contrib  
> deb http://mirrors.163.com/debian/ jessie-updates main non-free contrib
> EOF

更新apt源,安装curl:

apt-get update && apt-get install curl –y
curl -k https://www.baidu.com

docker commit -p a8a246374141  zhangyiwen0724/nginx:curl
docker push zhangyiwen0724/nginx:curl 传到仓库里

容器的数据在/data/docker/containers

Dockerfile
Dockerfile是什么?

Docker引擎通过读取dockerfile中指令自动化的构建镜像

Dockerfile构建镜像的几率是90%

User/workdir指令:

User:指定init进程是谁运行的
Workdir:以下的指令切换到此目录下,类似于linux中的cd命令

[root@elk2 /data/dockerfile]# cat Dockerfile 
FROM docker.io/zhangyiwen0724/nginx:v1.12.2
USER nginx
WORKDIR /usr/share/nginx/html

构建镜像:

-t 加tag
docker build . -t docker.io/zhangyiwen0724/nginx:v1.12.2_with_user_workdir

启动容器:

docker run --rm -ti --name nginx123 zhangyiwen0724/nginx:v1.12.2_with_user_workdir /bin/bash

Add/expose指令:

Add:类似于copy,但是比copy使用范围广
Expose:哪个端口被暴露出来

cp /root/html/index.html .

cat Dockerfile 
FROM docker.io/zhangyiwen0724/nginx:v1.12.2
ADD index.html /usr/share/nginx/html/index.html
EXPOSE 80

构建:

docker build . -t zhangyiwen0724/nginx:v1.12.2_with_index_expose

启动容器:
Expose指令只和-P使用生效

docker run --rm -it --name nginx123 -P zhangyiwen0724/nginx:v1.12.2_with_index_expose /bin/bash

nginx -g "daemon off;" 启动nginx

docker run --rm -d --name nginx123 -P zhangyiwen0724/nginx:v1.12.2_with_index_expose 

docker run --rm -d --name nginx123 -P zhangyiwen0724/nginx:v1.12.2_with_index_expose 

Run/env指令:

Ver是环境变量名
RUN:构建镜像时,执行一些可执行的命令

cat Dockerfile 
FROM centos:7
ENV VER 9.11.4
RUN yum install bind-$VER -y

构建:

docker build . -t zhangyiwen0724/bind:v9.11.4_with_env_run

bind 软件装到镜像里了。

验证:

docker run -it --rm zhangyiwen0724/bind:v9.11.4_with_env_run /bin/bash

Cmd/entrypoint指令:

Cmd:启动容器要执行什么命令

cat Dockerfile 
FROM centos:7
RUN yum install httpd -y
CMD ["httpd","-D","FOREGROUND"]

构建指令:

docker build . -t zhangyiwen0724/httpd:test

运行容器:

docker run -d --rm --name myhttpd -p83:80 zhangyiwen0724/httpd:test

ENTRYPOINT指令

cat Dockerfile 
FROM centos:7
ADD entrypoint.sh /entrypoint.sh
RUN yum install epel-release -q -y && yum install nginx -y
ENTRYPOINT /entrypoint.sh

cat entrypoint.sh 
#!/bin/bash
/sbin/nginx -g "daemon off;"
chmod +x entrypoint.sh
docker build . -t zhangyiwen0724/nginx:mynginx
docker run --rm zhangyiwen0724/nginx:mynginx
docker run --rm -p84:80 zhangyiwen0724/nginx:mynginx

403也说明nginx开启了。entrypoint.sh生效了

docker exec -ti competent_bohr /bin/bash

Dockerfile综合实验

运行一个docker容器,在浏览器打开demo.od.com能访问到百度首页

Dockerfile:

cat Dockerfile 
FROM zhangyiwen0724/nginx:v1.12.2
USER root
ENV WWW /usr/share/nginx/html
ENV CONF /etc/nginx/conf.d
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&
    echo 'Asia/Shanghai' >/etc/timezone
WORKDIR $WWW
ADD index.html $WWW/index.html
ADD demo.od.com.conf $CONF/demo.od.com.conf
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
cat demo.od.com.conf 
server {
   listen 80;
   server_name demo.od.com;

   root /usr/share/nginx/html;
}
wget www.baidu.com -O index.html

构建镜像:

docker build . -t zhangyiwen0724/nginx:baidu

启动容器:

docker run --rm -P zhangyiwen0724/nginx:baidu

因为要求是访问域名,所以此处应该绑定hosts,同时将容器内的80端口和宿主机的80端口绑定起来

172.16.108.138  http://demo.od.com/

Docker的网络模型

NAT模式

启动容器:

docker run -ti --rm centos /bin/sh

或者:

docker run -ti --rm alpine:3.13.1 /bin/sh

None模式

可以不提供http rpc tcp服务,只需要docker的计算资源

docker run -ti --rm --net=none alpine /bin/sh

Host模式

跟宿主机保持一致,没有隔离net,没有使用容器的网络。

docker run -ti --rm --net=host alpine /bin/sh

联合网络(两个容器共享一个命名空间)

启动一个nginx容器:

docker run -d zhangyiwen0724/nginx:v1.12.2

再起一个nginx:

docker run -ti --rm --net=container:fa29933706c2 zhangyiwen0724/nginx:curl bash

cat /etc/issue
apt-get update && apt-get install net-tools –y

docker run -it --rm --name lianhewangluo --net=container:fa29933706c2 zhangyiwen0724/nginx:curl /bin/bash
apt-get update && apt-get install net-tools –y

原文地址:https://www.cnblogs.com/even160941/p/14963562.html