k8s学习笔记-Docker篇

港控/mmm° 2022-10-26 12:45 318阅读 0赞

K8S学习笔记-Docker篇

Docker安装

Docker hello world 启动信息步骤

安装了docker后执行官方自带的hello-world镜像后,其执行步骤分析

  1. ~% docker run hello-world
  2. Unable to find image 'hello-world:latest' locally
  3. latest: Pulling from library/hello-world
  4. 0e03bdcc26d7: Pulling fs layer
  5. latest: Pulling from library/hello-world
  6. 0e03bdcc26d7: Pull complete
  7. Digest: sha256:31b9c7d48790f0d8c50ab433d9c3b7e17666d6993084c002c2ff1ca09b96391d
  8. Status: Downloaded newer image for hello-world:latest
  9. Hello from Docker!
  10. This message shows that your installation appears to be working correctly.
  11. To generate this message, Docker took the following steps:
  12. #第一步,docker 客户端联系了docker守护进程
  13. 1. The Docker client contacted the Docker daemon.
  14. #第二步,docker 守护进程将 hello-world镜像从dockerhub上拉取下来
  15. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
  16. (amd64)
  17. #第三步,docker守护进程使读取的镜像创建了一个新的容器,容器运行镜像的可执行文件
  18. 3. The Docker daemon created a new container from that image which runs the
  19. executable that produces the output you are currently reading.
  20. #第四步, Docker守护进程将输出流式传输到Docker客户端,后者将其发送到您的终端。
  21. 4. The Docker daemon streamed that output to the Docker client, which sent it
  22. to your terminal.
  23. To try something more ambitious, you can run an Ubuntu container with:
  24. $ docker run -it ubuntu bash
  25. Share images, automate workflows, and more with a free Docker ID:
  26. https://hub.docker.com/
  27. For more examples and ideas, visit:
  28. https://docs.docker.com/get-started/

Docker镜像结构

在这里插入图片描述

  1. 镜像的结构
  2. ${registry_name}/${repository_name}/${image_name}:${tag_name}
  3. docker.io/library/alpine:3.10.1

镜像管理

搜索镜像
  1. docker search alpine
下载镜像
  1. 下载最新版本镜像
  2. docker pull alpine
  3. 下载指定版本的tag的镜像
  4. docker pull alpine:3.10.3
  5. 镜像结构:registy_name/repository_name/image_name:tag_name
  6. 如: docker.io/library/alpine:3.10.1
  7. 如果在docker pull 指定版本镜像时报以下错误,说明需要登录docker
  8. 在终端输入docker login命令,然后用用户名密码登录即可,如果没有注册,
  9. 需要在docker.io进行注册
  10. Error response from daemon: Head https://registry-1.docker.io/v2/library/alpine/manifests/1.10.3: unauthorized: incorrect username or password
查看本地镜像
  1. docker images
  2. localhost ~ % docker images
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. alpine latest e50c909a8df2 10 days ago 5.61MB
  5. nginx latest f35646e83998 3 months ago 133MB
从镜像仓库中查找镜像

登录docker.io,然后在搜索框中搜索需要查找的镜像名称,进入相应的镜像页面
在这里插入图片描述
在tags目录下就能看到镜像的标签
在这里插入图片描述
在右侧可以复制下载相应标签的docker命令
在这里插入图片描述
执行命令即可下载相应的标签的镜像

  1. localhost ~ % docker pull alpine:3.13.1
  2. 3.13.1: Pulling from library/alpine
  3. Digest: sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930
  4. Status: Downloaded newer image for alpine:3.13.1
  5. docker.io/library/alpine:3.13.1
给镜像打标签,并推送镜像

打标签的命令格式为
docker tag 镜像id ${registry_name}/${repository_name}/${image_name}:${tag_name}

  1. localhost ~ % docker tag e50c909a8df2 docker.io/wejack639/alpine:3.13.1
  2. localhost ~ % docker images
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. alpine 3.13.1 e50c909a8df2 10 days ago 5.61MB
  5. wejack639/alpine 3.13.1 e50c909a8df2 10 days ago 5.61MB

推送镜像标签的命令为

docker push ${registry_name}/${repository_name}/${image_name}:${tag_name}

  1. localhost ~ % docker push docker.io/wejack639/alpine:3.13.1
  2. The push refers to repository [docker.io/wejack639/alpine]
  3. # Mounted from 说明这个是直接挂载了docker.io的镜像仓库的镜像,因为镜像id是已有的,并没有将本地的镜像文件推到上面
  4. 1119ff37d4a9: Mounted from library/alpine
  5. 3.13.1: digest: sha256:3747d4eb5e7f0825d54c8e80452f1e245e24bd715972c919d189a62da97af2ae size: 528

然后在docker.io上就能查到自己的镜像信息了

在这里插入图片描述

删除镜像标签

docker rmi ${image_name}:${tag_name}

  1. docker rmi wejack639/alpine:3.13.1
  2. Untagged: wejack639/alpine:3.13.1
  3. Untagged: wejack639/alpine@sha256:3747d4eb5e7f0825d54c8e80452f1e245e24bd715972c919d189a62da97af2ae
删除镜像

`docker rmi ${imageId}

  1. localhost ~ % docker rmi e50c909a8df2
  2. #这里的响应是因为这个镜像有多个标签在用,如果要删除则必须强制,加-f命令
  3. Error response from daemon: conflict: unable to delete e50c909a8df2 (must be forced) - image is referenced in multiple repositories
  4. localhost ~ % docker rmi -f e50c909a8df2
  5. Untagged: alpine:3.13.1
  6. Untagged: alpine:latest
  7. Untagged: alpine@sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930
  8. Deleted: sha256:e50c909a8df2b7c8b92a6e8730e210ebe98e5082871e66edd8ef4d90838cbd25

容器的基本操作

查看本地所有的容器

docker ps -a

  1. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  2. e062310c1c18 alpine:latest "/bin/sh" 23 hours ago Exited (0) 23 hours ago fervent_neumann
  3. 3ba9e1ebb6ff e7d92cdc71fe "/bin/sh" 23 hours ago Exited (0) 23 hours ago jovial_feynman

其中image的名称,应该根据名称和镜像的结构
${registry_name}/${repository_name}/${image_name}:${tag_name}
快速反应出该镜像的地址为 docker.io/library/alpine:latest

启动容器

docker run
命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
OPTIONS:
-i:启动一个可交互容器,并持续打开标准输入
-t:使终端关联到的窗口的标准输入输出上
-d:容器放置到后台运行
-rm:退出后即删除窗口
-name:指定容器的唯一名称
IMAGE:要运行的镜像
COMMAND:启动容器时要运行的命令

交互启动容器
  1. docker run -it alpine:latest /bin/sh
非交互启动容器
  1. docker run --rm alpine:latest /bin/echo hello
后台启动容器
  1. docker run -d --name sleeptest alpine:latest /bin/sleep 60
  2. 宿主机查看后台容器进程
  3. ps aux | grep sleeptest
  4. 进入状态为UP的容器,参数为容器id
  5. docker exec -it e31d1845bf1e /bin/sh
停止容器
  1. docker stop containerId
重启容器
  1. docker restart containerId
删除容器
  1. docker rm containerId
  2. docker rm -f containerId

容器的高级操作

docker -v

映射目录

docker -p

映射端口测试

docker -e

配置窗口环境变量,同时指定多个变量使用多个-e

  1. # docker -p -v 测试
  2. ## 下载 nginx镜像
  3. docker pull nginx:1.19.7
  4. ## 将面试页面保存为html文件,放到docker映射目录中
  5. curl http://www.baidu.com >> /Users/domino/files/docker-share/nginx/html/bd.html
  6. ## 要注意的是无论是端口还是目录,都是本地的在前,容器内的在后
  7. docker run --name my_nginx -d -p 8100:80 -v /Users/domino/files/docker-share/nginx/html:/usr/share/nginx/html nginx:1.19.7
  8. 如上面的命令执行完以后,访问localhost:8100/baidu.html ,就可以展示百度页面了
  9. # docker -e测试
  10. % docker run --rm -e A_OPTs=abcde -e B_OPTS=efghi alpine:3.10.3 printenv
  11. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  12. HOSTNAME=8f1f65af55b3
  13. B_OPTS=efghi
  14. A_OPTs=abcde
  15. HOME=/root

容器的生命周期

  • 检查本地是否存在镜像,如果不存在就从远端仓库获取
  • 利用镜像启动容器
  • 分配一个文件系统,并在只读的镜像层外挂载一层可读写层
  • 从宿主机配置的网桥接口中桥接一个虚拟接口到容器
  • 从地址池配置一个ip地址给容器
  • 执行用户指定的指令
  • 执行完毕后容器终止

容器的生命周期

dockerfile

Dockerfile 相关的官方文档 官方文档

dockerfile 定义

dockerfile是用于构建docker镜像的代码

  • docker 可以根据dockerfile自动构建镜像
  • dockerfile为文本格式,是构建镜像所需命令的清单
  • 通过docker build命令可以自动创建
  • 90%以上的生产docker镜像是通过dockerfile进行构建的

dockerfile的规则

  1. 格式

    • #为注释
    • 指令大小写不敏感,但是建议指令用大写,内容用小写
  2. Docker会按从上到下的顺序执行dockerfile中的指令
  3. 每个Dockerfile的第一个非注释指令必须为From

4组Dockerfile的核心指令

  • USER/WORKDIR指令

    以下就是一个通过Dockerfile进行创建镜像的Dockerfile的内容 ,要注意的是文件名必须为Dockerfile

    1. ~% cat Dockerfile
    2. # 使用my_nginx:1.0.0镜像进行构建
    3. FROM docker.io/wejack639/my_nginx:1.0.0
    4. # 指明docker中主进程使用用户nginx运行
    5. USER root
    6. # 跳转到 容器的这个目录下
    7. WORKDIR /usr/share/nginx/html
  1. # -t参数是打tag的意思,后面的是tag的名称
  2. ~% docker build . -t docker.io/wejack639/my_nginx:v1.0.0_from_dockerfile
  3. Sending build context to Docker daemon 2.048kB
  4. Step 1/3 : FROM docker.io/wejack639/my_nginx:1.0.0
  5. ---> 36a00a4ac6fa
  6. Step 2/3 : USER nginx
  7. ---> Running in cac95510a31b
  8. Removing intermediate container cac95510a31b
  9. ---> cb3aeb9af26d
  10. Step 3/3 : WORKDIR /Users/domino/files/docker-share/nginx/html:/usr/share/nginx/html
  11. ---> Running in 6d52fb71783d
  12. Removing intermediate container 6d52fb71783d
  13. ---> be494687e403
  14. Successfully built be494687e403
  15. Successfully tagged wejack639/my_nginx:v1.0.0_from_dockerfile
  16. # 然后就可以看到新打的镜像了
  17. ~% docker images
  18. REPOSITORY TAG IMAGE ID CREATED SIZE
  19. wejack639/my_nginx 1.0.0_from_dockerfile 94e75eb9f24f 16 seconds ago 57.9MB
  20. # 使用镜像启动容器后,进入容器,使用pwd命令可以看到当前所在的目录为 Dockerfile内WORKDIR指定的目录
  21. % docker run -d 94e75eb9f24f
  22. 950045fc3b52fa77ba85ea106346b80ffaacc07d676f12338d14c9c0ad5e85f0
  23. % docker exec -it 950045fc3b52 /bin/bash
  24. bash-4.3# pwd
  25. /usr/share/nginx/html
  • ADD/EXPOSE指令

    ADD命令的意思是添加文件到容器内

    1. 如:下面的意思就是将当前目录的index.html文件添加到镜像的 /usr/share/nginx/html/index.html 文件位置,这里要带文件名
    2. ADD index.html /usr/share/nginx/html/index.html

    EXPOSE 命令是标明容器内服务暴露端口,只是标明,就是告诉你提供服务的进程的端口是8080,但是实际是什么并不受expose命令的影响,下面的是官方的文档里的说明,最终实际的映射用的还是-P

    The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

    EXPOSE指令通知Docker容器在运行时在指定的网络端口上进行侦听。 您可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。

    The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

    EXPOSE指令实际上不会发布端口。 它充当构建映像的人员和运行容器的人员之间的一种文档,即有关打算发布哪些端口的信息。 要在运行容器时实际发布端口,请在docker run上使用-p标志发布并映射一个或多个端口,或使用-P标志发布所有公开的端口并将其映射到高阶端口。

    测试代码

    1. # Dockerfile文件内容
    2. FROM docker.io/nginx:1.19.7
    3. ADD index.html /usr/share/nginx/html/index.html
    4. #这里EXPOSE我写啥都不会影响 docker运行使用的端口,可以理解只是一行注释
    5. EXPOSE 80
    6. #在Dockerfile文件所在目录执行命令
    7. ~% docker build . -t wejack639/my_nginx:1.19.7_add_expose
    8. Sending build context to Docker daemon 5.12kB
    9. Step 1/3 : FROM docker.io/nginx:1.19.7
    10. ---> 35c43ace9216
    11. Step 2/3 : ADD index.html /usr/share/nginx/html/index.html
    12. ---> 4adb37c70fe2
    13. Step 3/3 : EXPOSE 80
    14. ---> Running in 2838417b3abf
    15. Removing intermediate container 2838417b3abf
    16. ---> 192fb2dab8d5
    17. Successfully built 192fb2dab8d5
    18. Successfully tagged wejack639/my_nginx:1.19.7_add_expose
    19. # 查看生成的镜像
    20. ~% docker images
    21. REPOSITORY TAG IMAGE ID CREATED SIZE
    22. wejack639/my_nginx 1.19.7_add_expose 192fb2dab8d5 About a minute ago 133MB
    23. # 启动镜像, -P (大写的P命令会将随机端口指向容器的内的实际端口)
    24. % docker run --name my_nginx_add_expose -d -P wejack639/my_nginx:1.19.7_add_expose
    25. 0ee3a387ed1d68e81bf4df9a54d605f304ad21225acf1d69d81a50cd88f9e0b2
    26. # 查看启动的镜像
    27. % docker ps
    28. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    29. 0ee3a387ed1d wejack639/my_nginx:1.19.7_add_expose "/docker-entrypoint.…" 40 seconds ago Up 39 seconds 0.0.0.0:55018->80/tcp my_nginx_add_expose

    镜像中打了一个百度首页的源码,所以访问 localhost:55018 可以访问到容器内的页面
    71faa6f0763fc0d2bc9bd493ee8ba2a5.png

    最开始对EXPOSE 指令的理解有误,所以做测试的时候,走了一些弯路,要注意的是 EXPOSE 指令只是理解为是一个注释说明一样的指令,后面配置的端口信息和实际上容器内进程运行使用的端口可能不一样

  • RUN/ENV指令

    RUN 指令会在构建镜像时执行RUN指令后面的命令,比如安装一些常用软件之类的
    ENV 指令会增加环境变量

    1. # 查看Dockerfile文件
    2. % cat Dockerfile
    3. FROM docker.io/centos:7
    4. # 增加 JAVA_HOME环境变量
    5. ENV JAVA_HOME /etc/java_home
    6. # 安装openssh-server
    7. RUN yum install -y openssh-server
    8. # 构建命令执行后可以看到环境变量和安装都执行了
    9. % docker build . -t wejack639/centos:7_run_env
    10. Sending build context to Docker daemon 2.048kB
    11. Step 1/3 : FROM docker.io/centos:7
    12. ---> 8652b9f0cb4c
    13. Step 2/3 : ENV JAVA_HOME /etc/java_home
    14. ---> Running in a287bc8ee5fa
    15. Removing intermediate container a287bc8ee5fa
    16. ---> 6f005109136e
    17. Step 3/3 : RUN yum install -y openssh-server
    18. ---> Running in dc675a57ad25
    19. Loaded plugins: fastestmirror, ovl
    20. Determining fastest mirrors
    21. * base: mirrors.huaweicloud.com
    22. * extras: mirrors.bfsu.edu.cn
    23. * updates: mirrors.huaweicloud.com
    24. Resolving Dependencies
    25. --> Running transaction check
    26. ---> Package openssh-server.x86_64 0:7.4p1-21.el7 will be installed
    27. # 启动镜像后
    28. % docker run --name "mycentos_run_env" -it -d --privileged -p 20020:22 wejack639/centos:7_run_env
    29. d2d07d574545f98431f5d41e1a20a03e5f552a7bb9678060719cde7b34528f03
    30. % docker exec -it d2d07d574545 /bin/bash
    31. # 打印环境变量
    32. [root@d2d07d574545 /]# printenv
    33. HOSTNAME=d2d07d574545
    34. JAVA_HOME=/etc/java_home
    35. # 查看 openssh服务 ,也已经安装了
    36. [root@d2d07d574545 /]# rpm -qa openssh
    37. openssh-7.4p1-21.el7.x86_64
  • CMD/ENTRYPOINT指令

    CMD 启动容器以后执行的命令

    测试

    1. # Dockerfile文件内容
    2. ~ % cat Dockerfile
    3. FROM docker.io/centos:7
    4. # 打镜像时安装 httpd
    5. RUN yum install -y httpd
    6. # 容器启动以后启动httpd
    7. CMD ["httpd","-D","FOREGROUND"]
    8. # 使用Dockerfile 打镜像
    9. ~% docker build . -t wejack639/mycentos:7_cmd
    10. # 启动镜像,将宿主机的 25888端口与容器的80端口映射
    11. ~% docker run --name "mycentos_cmd" -d -p 25888:80 wejack639/mycentos:7_cmd

    访问 http://localhost:25888 即可展示 httpd服务的默认页面

    51c205ea65a2f038c1799e12e94296ad.png

    ENTRYPOINT 指令一般容器如果没有CMD命令或在/下没有 entrypoint.sh 会执行ENTRYPOINT 指令下配置的文件

    测试

    1. # 首先定义 Dockerfile文件
    2. ~% cat Dockerfile
    3. # 使用nginx镜像做为基础镜像
    4. FROM docker.io/nginx:1.19.7
    5. # 添加 entrypoint.sh文件到 /目录下
    6. ADD entrypoint.sh /entrypoint.sh
    7. # 添加 测试首页
    8. ADD index.html /usr/share/nginx/html/index.html
    9. # 指定 ENTRYPONT 使用的命令文件,如果不使用命令文件,可以直接使用命令格式为 ENTRYPOINT ["executable", "param1", "param2"]
    10. # 参考 https://docs.docker.com/engine/reference/builder/#entrypoint
    11. ENTRYPOINT /entrypoint.sh
  1. # 本地创建entrypoint.sh文件,这里要注意给 entrypoint.sh文件添加 可执行权限
  2. # chmod a+x entrypoint.sh
  3. # nginx 执行daemon off的原因为nginx默认是以后台模式启动的,Docker未执行自定义的CMD之前,nginx的pid是1,执行到CMD之后,nginx就在后台运行,bash或sh脚本的pid变成了1。所以一旦执行完自定义CMD,nginx容器也就退出了。为了保持nginx的容器不退出,应该关闭nginx后台运行
  4. ~% cat entrypoint.sh
  5. !#/bin/bash
  6. touch /hello.txt
  7. echo "hello world" >> /hello.txt
  8. /usr/sbin/nginx -g "daemon off;"
  9. # 构建镜像
  10. ~% docker build . -t wejack639/my_nginx:1.19.7_entrypoint1
  11. # 启动容器
  12. ~% docker run --name "my_nginx_entrypoint1" -d -p 25888:80 wejack639/my_nginx:1.19.7_entrypoint1
  13. # 进入容器
  14. ~% docker exec -it fb4b9205a36b /bin/bash
  15. 进入容器的根目录后,可以看到 在/目录下有 `entrypoint.sh`文件 ,也有我在`entrypoint.sh` 文件中执行创建的hello.txt文件

发表评论

表情:
评论列表 (有 0 条评论,318人围观)

还没有评论,来说两句吧...

相关阅读