2020.07.22-Docker基础

范书
2023-12-01

Docker基础

这篇基础文章是方便用户在使用cSphere平台之前,了解docker基础知识。

针对已经有一定的Linux基础知识的用户。

Docker是什么

Docker是一个改进的容器技术。具体的“改进”体现在,Docker为容器引入了镜像,使得容器可以从预先定义好的模版(images)创建出来,并且这个模版还是分层的。

Docker经常被提起的特点:

轻量,体现在内存占用小,高密度
快速,毫秒启动
隔离,沙盒技术更像虚拟机
Docker技术的基础:
namespace,容器隔离的基础,保证A容器看不到B容器. 6个名空间:User,Mnt,Network,UTS,IPC,Pid
cgroups,容器资源统计和隔离。主要用到的cgroups子系统:cpu,blkio,device,freezer,memory
unionfs,典型:aufs/overlayfs,分层镜像实现的基础

Docker组件:

docker Client客户端————>向docker服务器进程发起请求,如:创建、停止、销毁容器等操作
docker Server服务器进程—–>处理所有docker的请求,管理所有容器
docker Registry镜像仓库——>镜像存放的中央仓库,可看作是存放二进制的scm

Docker安装

Docker的安装非常简单,支持目前所有主流操作系统,从Mac到Windows到各种Linux发行版
具体参考: docker安装

Docker常见命令

容器相关操作

docker create # 创建一个容器但是不启动它
docker run # 创建并启动一个容器
docker stop # 停止容器运行,发送信号SIGTERM
docker start # 启动一个停止状态的容器
docker restart # 重启一个容器
docker rm # 删除一个容器
docker kill # 发送信号给容器,默认SIGKILL
docker attach # 连接(进入)到一个正在运行的容器
docker wait # 阻塞到一个容器,直到容器停止运行

获取容器相关信息

docker ps # 显示状态为运行(Up)的容器
docker ps -a # 显示所有容器,包括运行中(Up)的和退出的(Exited)
docker inspect # 深入容器内部获取容器所有信息
docker logs # 查看容器的日志(stdout/stderr)
docker events # 得到docker服务器的实时的事件
docker port # 显示容器的端口映射
docker top # 显示容器的进程信息
docker diff # 显示容器文件系统的前后变化

导出容器

docker cp # 从容器里向外拷贝文件或目录
docker export # 将容器整个文件系统导出为一个tar包,不带layers、tag等信息
执行
docker exec # 在容器里执行一个命令,可以执行bash进入交互式

镜像操作

docker images # 显示本地所有的镜像列表
docker import # 从一个tar包创建一个镜像,往往和export结合使用
docker build # 使用Dockerfile创建镜像(推荐)
docker commit # 从容器创建镜像
docker rmi # 删除一个镜像
docker load # 从一个tar包创建一个镜像,和save配合使用
docker save # 将一个镜像保存为一个tar包,带layers和tag信息
docker history # 显示生成一个镜像的历史命令
docker tag # 为镜像起一个别名

镜像仓库(registry)操作

docker login # 登录到一个registry
docker search # 从registry仓库搜索镜像
docker pull # 从仓库下载镜像到本地
docker push # 将一个镜像push到registry仓库中
获取Container IP地址(Container状态必须是Up)
docker inspect id | grep IPAddress | cut -d ‘"’ -f 4

获取端口映射

docker inspect -f ‘{{range $p, KaTeX parse error: Expected 'EOF', got '}' at position 31: …kSettings.Ports}̲} {{p}} -> {{(index $conf 0).HostPort}} {{end}}’ id

获取环境变量

docker exec container_id env

杀掉所有正在运行的容器

docker kill $(docker ps -q)

删除老的(一周前创建)容器

docker ps -a | grep ‘weeks ago’ | awk ‘{print $1}’ | xargs docker rm

删除已经停止的容器

docker rm docker ps -a -q

删除所有镜像,小心

docker rmi $(docker images -q)
Dockerfile
Dockerfile是docker构建镜像的基础,也是docker区别于其他容器的重要特征,正是有了Dockerfile,docker的自动化和可移植性才成为可能。

不论是开发还是运维,学会编写Dockerfile几乎是必备的,这有助于你理解整个容器的运行。

FROM , 从一个基础镜像构建新的镜像
FROM ubuntu
MAINTAINER , 维护者信息
MAINTAINER William wlj@nicescale.com
ENV , 设置环境变量
ENV TEST 1
RUN , 非交互式运行shell命令
RUN apt-get -y update
RUN apt-get -y install nginx
ADD , 将外部文件拷贝到镜像里,src可以为url
ADD http://nicescale.com/ /data/nicescale.tgz
WORKDIR /path/to/workdir, 设置工作目录
WORKDIR /var/www
USER , 设置用户ID
USER nginx
VULUME <#dir>, 设置volume
VOLUME [‘/data’]
EXPOSE , 暴露哪些端口
EXPOSE 80 443
ENTRYPOINT [‘executable’, ‘param1’,’param2’]执行命令
ENTRYPOINT ["/usr/sbin/nginx"]
CMD [“param1”,”param2”]
CMD [“start”]
docker创建、启动container时执行的命令,如果设置了ENTRYPOINT,则CMD将作为参数

Dockerfile最佳实践

尽量将一些常用不变的指令放到前面
CMD和ENTRYPOINT尽量使用json数组方式

通过Dockerfile构建image

docker build csphere/nginx:1.7 .

镜像仓库Registry

镜像从Dockerfile build生成后,需要将镜像推送(push)到镜像仓库。企业内部都需要构建一个私有docker registry,这个registry可以看作二进制的scm,CI/CD也需要围绕registry进行。

部署registry

mkdir /registry
docker run -p 80:5000 -e STORAGE_PATH=/registry -v /registry:/registry registry:2.0

推送镜像保存到仓库

假设192.168.1.2是registry仓库的地址:

docker tag csphere/nginx:1.7 192.168.1.2/csphere/nginx:1.7
docker push 192.168.1.2/csphere/nginx:1.7
几个简单小例子

容器操作

1.创建并拉取busybox

#docker run -it --name con01 busybox:latest
/ # ip addr #容器里执行
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
Segmentation fault (core dumped)
/ # ping www.csphere.cn
PING www.csphere.cn (117.121.26.243): 56 data bytes
64 bytes from 117.121.26.243: seq=0 ttl=48 time=3.139 ms
64 bytes from 117.121.26.243: seq=1 ttl=48 time=3.027 ms
^C
— www.csphere.cn ping statistics —
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 3.027/3.083/3.139 ms
exit #退出容器

2.创建测试容器

docker run -d --name con03 csphere/test:0.1
efc9bda4a2ff2f479b18e0fc4698e42c47c9583a24c93f5ce6b28a828a172709

3.登陆到con03中

#docker exec -it con03 /bin/bash
[root@efc9bda4a2ff /]# exit

4.停止con03

#docker stop con03
con03

5.开启con03

#docker start con03
con03

6.删除con03

#docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efc9bda4a2ff csphere/test:0.1 "/usr/local/bin/run 4 minutes ago Up 17 seconds con03
99aa6ee25adc busybox:latest “/bin/sh” 14 minutes ago Exited (0) 12 minutes ago con02
831c93de9b9f busybox:latest “/bin/sh” 2 hours ago Up 27 minutes con01
#docker rm con02 #容器停止的状态
#docker rm -f con03 #容器开启的状态

镜像操作

1.从docker hub官方镜像仓库拉取镜像

#docker pull busybox:latest
atest: Pulling from busybox
cf2616975b4a: Pull complete
6ce2e90b0bc7: Pull complete
8c2e06607696: Already exists
busybox:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:38a203e1986cf79639cfb9b2e1d6e773de84002feea2d4eb006b52004ee8502d
Status: Downloaded newer image for busybox:latest

2.从本地上传镜像到镜像仓库

docker push 192.168.1.2/csphere/nginx:1.7

3.查找镜像仓库的某个镜像

#docker search centos/nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
johnnyzheng/centos-nginx-php-wordpress 1 [OK]
sergeyzh/centos6-nginx 1 [OK]
hzhang/centos-nginx 1 [OK]

4.查看本地镜像列表

#docker images
TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/csphere/csphere 0.10.3 604c03bf0c9e 3 days ago 62.72 MB
docker.io/csphere/csphere latest 604c03bf0c9e 3 days ago 62.72 MB
csphere/csphere 0.10.3 604c03bf0c9e 3 days ago 62.72 MB
registry 2.0 2971b6ce766c 7 days ago 548.1 MB
busybox latest 8c2e06607696 3 weeks ago 2.43 MB

5.删除镜像

docker rmi busybox:latest #没有容器使用此镜像创建,如果有容器在使用此镜像会报错:Error response from daemon: Conflict, cannot delete 8c2e06607696 because the running container 831c93de9b9f is using it, stop it and use -f to force
FATA[0000] Error: failed to remove one or more images
docker rmi -f busybox:latest #容器使用此镜像创建,此容器状态为Exited

6.查看构建镜像所用过的命令

#docker history busybox:latest
IMAGE CREATED CREATED BY SIZE
8c2e06607696 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0 B
6ce2e90b0bc7 3 weeks ago /bin/sh -c #(nop) ADD file:8cf517d90fe79547c4 2.43 MB
cf2616975b4a 3 weeks ago /bin/sh -c #(nop) MAINTAINER Jérôme Petazzo 0 B
Tagged on: docker

Docker guildes

Orientation and setup

Estimated reading time: 4 minutes
Orientation and setupBuild and run your imageShare images on Docker Hub
Welcome! We are excited that you want to learn Docker.

This page contains step-by-step instructions on how to get started with Docker. We also recommend the video walkthrough from Dockercon 2020.

The Docker Quickstart training module teaches you how to:

Set up your Docker environment (on this page)

Build and run your image

Share images on Docker Hub

Docker concepts

Docker is a platform for developers and sysadmins to build, run, and share applications with containers. The use of containers to deploy applications is called containerization. Containers are not new, but their use for easily deploying applications is.

Containerization is increasingly popular because containers are:

Flexible: Even the most complex applications can be containerized.
Lightweight: Containers leverage and share the host kernel, making them much more efficient in terms of system resources than virtual machines.
Portable: You can build locally, deploy to the cloud, and run anywhere.
Loosely coupled: Containers are highly self sufficient and encapsulated, allowing you to replace or upgrade one without disrupting others.
Scalable: You can increase and automatically distribute container replicas across a datacenter.
Secure: Containers apply aggressive constraints and isolations to processes without any configuration required on the part of the user.
Images and containers
Fundamentally, a container is nothing but a running process, with some added encapsulation features applied to it in order to keep it isolated from the host and from other containers. One of the most important aspects of container isolation is that each container interacts with its own private filesystem; this filesystem is provided by a Docker image. An image includes everything needed to run an application - the code or binary, runtimes, dependencies, and any other filesystem objects required.

Containers and virtual machines

A container runs natively on Linux and shares the kernel of the host machine with other containers. It runs a discrete process, taking no more memory than any other executable, making it lightweight.

By contrast, a virtual machine (VM) runs a full-blown “guest” operating system with virtual access to host resources through a hypervisor. In general, VMs incur a lot of overhead beyond what is being consumed by your application logic.

Container stack example Virtual machine stack example
Set up your Docker environment
Download and install Docker Desktop
Docker Desktop is an easy-to-install application for your Mac or Windows environment that enables you to start coding and containerizing in minutes. Docker Desktop includes everything you need to build, run, and share containerized applications right from your machine.

Follow the instructions appropriate for your operating system to download and install Docker Desktop:

Docker Desktop for Mac
Docker Desktop for Windows
Test Docker version
After you’ve successfully installed Docker Desktop, open a terminal and run docker --version to check the version of Docker installed on your machine.

$ docker --version
Docker version 19.03.12, build 48a66213fe

Test Docker installation

Test that your installation works by running the hello-world Docker image:

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

Run docker image ls to list the hello-world image that you downloaded to your machine.

List the hello-world container (spawned by the image) which exits after displaying its message. If it is still running, you do not need the --all option:

$ docker ps --all

CONTAINER ID     IMAGE           COMMAND      CREATED            STATUS
54f4984ed6a8     hello-world     "/hello"     20 seconds ago     Exited (0) 19 seconds ago

Conclusion

At this point, you’ve installed Docker Desktop on your development machine, and ran a quick test to ensure you are set up to build and run your first containerized application.

On to Part 2 >>

CLI references

Refer to the following topics for further documentation on all CLI commands used in this article:

docker version
docker run
docker image
docker container
get started, setup, orientation, quickstart, intro, concepts, containers, docker desktop

Build and run your image

Estimated reading time: 8 minutes
Orientation and setupBuild and run your imageShare images on Docker Hub

Prerequisites

Work through the orientation and setup in Part 1.

Introduction

Now that you’ve set up your development environment, you can begin to develop containerized applications. In general, the development workflow looks like this:
Create and test individual containers for each component of your application by first creating Docker images.
Assemble your containers and supporting infrastructure into a complete application.
Test, share, and deploy your complete containerized application.

In this stage of the tutorial, let’s focus on step 1 of this workflow: creating the images that your containers will be based on. Remember, a Docker image captures the private filesystem that your containerized processes will run in; you need to create an image that contains just what your application needs to run.

Set up

Let us download the node-bulletin-board example project. This is a simple bulletin board application written in Node.js.

Git

Windows (without Git)
Mac or Linux (without Git)
Git
If you are using Git, you can clone the example project from GitHub:

git clone https://github.com/dockersamples/node-bulletin-board
cd node-bulletin-board/bulletin-board-app
Define a container with Dockerfile
After downloading the project, take a look at the file called Dockerfile in the bulletin board application. Dockerfiles describe how to assemble a private filesystem for a container, and can also contain some metadata describing how to run a container based on this image.

For more information about the Dockerfile used in the bulletin board application, see Sample Dockerfile.

Build and test your image

Now that you have some source code and a Dockerfile, it’s time to build your first image, and make sure the containers launched from it work as expected.

Make sure you’re in the directory node-bulletin-board/bulletin-board-app in a terminal or PowerShell using the cd command. Run the following command to build your bulletin board image:

docker build --tag bulletinboard:1.0 .

You’ll see Docker step through each instruction in your Dockerfile, building up your image as it goes. If successful, the build process should end with a message Successfully tagged bulletinboard:1.0.

Windows users:

This example uses Linux containers. Make sure your environment is running Linux containers by right-clicking on the Docker logo in your system tray, and clicking Switch to Linux containers. Don’t worry - all the commands in this tutorial work the exact same way for Windows containers.

You may receive a message titled ‘SECURITY WARNING’ after running the image, noting the read, write, and execute permissions being set for files added to your image. We aren’t handling any sensitive information in this example, so feel free to disregard the warning in this example.

Run your image as a container

Run the following command to start a container based on your new image:

docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0
There are a couple of common flags here:

–publish asks Docker to forward traffic incoming on the host’s port 8000 to the container’s port 8080. Containers have their own private set of ports, so if you want to reach one from the network, you have to forward traffic to it in this way. Otherwise, firewall rules will prevent all network traffic from reaching your container, as a default security posture.
–detach asks Docker to run this container in the background.
–name specifies a name with which you can refer to your container in subsequent commands, in this case bb.
Visit your application in a browser at localhost:8000. You should see your bulletin board application up and running. At this step, you would normally do everything you could to ensure your container works the way you expected; now would be the time to run unit tests, for example.

Once you’re satisfied that your bulletin board container works correctly, you can delete it:

docker rm --force bb

The --force option stops a running container, so it can be removed. If you stop the container running with docker stop bb first, then you do not need to use --force to remove it.

Conclusion

At this point, you’ve successfully built an image, performed a simple containerization of an application, and confirmed that your app runs successfully in its container. The next step will be to share your images on Docker Hub, so they can be easily downloaded and run on any destination machine.

On to Part 3 >>

Deploying to the cloud

To run your containers in the cloud with either Azure or AWS, check out our docs on getting started with cloud deployments.

Deploying with Docker and AWS
Deploying with Docker and Azure
Sample Dockerfile
Writing a Dockerfile is the first step to containerizing an application. You can think of these Dockerfile commands as a step-by-step recipe on how to build up your image. The Dockerfile in the bulletin board app looks like this:

#Use the official image as a parent image.
FROM node:current-slim

#Set the working directory.
WORKDIR /usr/src/app

#Copy the file from your host to your current location.
COPY package.json .

#Run the command inside your image filesystem.
RUN npm install

#Add metadata to the image to describe which port the container is listening on at runtime.
EXPOSE 8080

#Run the specified command within the container.
CMD [ “npm”, “start” ]

#Copy the rest of your app’s source code from your host to your image filesystem.
COPY . .
The dockerfile defined in this example takes the following steps:

Start FROM the pre-existing node:current-slim image. This is an official image, built by the node.js vendors and validated by Docker to be a high-quality image containing the Node.js Long Term Support (LTS) interpreter and basic dependencies.
Use WORKDIR to specify that all subsequent actions should be taken from the directory /usr/src/app in your image filesystem (never the host’s filesystem).
COPY the file package.json from your host to the present location (.) in your image (so in this case, to /usr/src/app/package.json)
RUN the command npm install inside your image filesystem (which will read package.json to determine your app’s node dependencies, and install them)
COPY in the rest of your app’s source code from your host to your image filesystem.
You can see that these are much the same steps you might have taken to set up and install your app on your host. However, capturing these as a Dockerfile allows you to do the same thing inside a portable, isolated Docker image.

The steps above built up the filesystem of our image, but there are other lines in your Dockerfile.

The CMD directive is the first example of specifying some metadata in your image that describes how to run a container based on this image. In this case, it’s saying that the containerized process that this image is meant to support is npm start.

The EXPOSE 8080 informs Docker that the container is listening on port 8080 at runtime.

What you see above is a good way to organize a simple Dockerfile; always start with a FROM command, follow it with the steps to build up your private filesystem, and conclude with any metadata specifications. There are many more Dockerfile directives than just the few you see above. For a complete list, see the Dockerfile reference.

CLI references
Further documentation for all CLI commands used in this article are available here:

docker image
docker container
Dockerfile reference
containers, images, dockerfiles, node, code, coding, build, push, run

Share images on Docker Hub
Estimated reading time: 3 minutes
Orientation and setupBuild and run your imageShare images on Docker Hub
Prerequisites
Work through the steps to build an image and run it as a containerized application in Part 2.

Introduction
At this point, you’ve built a containerized application described in Part 2 on your local development machine.

The final step in developing a containerized application is to share your images on a registry like Docker Hub, so they can be easily downloaded and run on any destination machine.

Set up your Docker Hub account
If you don’t have a Docker ID, follow these steps to create one. A Docker ID allows you to share images on Docker Hub.

Visit the Docker Hub sign up page.

Fill out the form and submit to create your Docker ID.

Verify your email address to complete the registration process.

Click on the Docker icon in your toolbar or system tray, and click Sign in / Create Docker ID.

Fill in your new Docker ID and password. After you have successfully authenticated, your Docker ID appears in the Docker Desktop menu in place of the ‘Sign in’ option you just used.

You can also sign into Docker Hub from the command line by typing docker login.

Create a Docker Hub repository and push your image
Before creating a repository, ensure you’ve set up your Docker Hub account and have connected it to your Docker Desktop.

Now let’s create your first repository, and push your bulletin board image to Docker Hub.

Click on the Docker icon in your menu bar, and navigate to Repositories > Create. You’ll be redirected to the Create Repository page on Docker Hub.

Type the repository name as bulletinboard and click Create at the bottom of the page. Do not fill any other details for now.

make a repo

You are now ready to share your image on Docker Hub, however, there’s one thing you must do first: images must be namespaced correctly to share on Docker Hub. Specifically, you must name images like /:.

Make sure you’re in the node-bulletin-board/bulletin-board-app directory in a terminal or PowerShell then and run:

docker tag bulletinboard:1.0 /bulletinboard:1.0
Finally, push your image to Docker Hub:

docker push /bulletinboard:1.0
Visit your repository in Docker Hub, and you’ll see your new image there. Remember, Docker Hub repositories are public by default.

Having trouble pushing? Remember, you must be signed into Docker Hub through Docker Desktop or the command line, and you must also name your images correctly, as per the above steps. If the push seemed to work, but you don’t see it in Docker Hub, refresh your browser after a couple of minutes and check again.

Conclusion
Now that your image is available on Docker Hub, you’ll be able to run it anywhere. If you try to use it on a new machine that doesn’t have it yet, Docker will automatically try and download it from Docker Hub. By moving images around in this way, you no longer need to install any dependencies except Docker on the machines you want to run your software on. The dependencies of containerized applications are completely encapsulated and isolated within your images, which you can share using Docker Hub as described above.

Another thing to keep in mind: at the moment, you’ve only pushed your image to Docker Hub; what about your Dockerfile? A crucial best practice is to keep these in version control, perhaps alongside your source code for your application. You can add a link or note in your Docker Hub repository description indicating where these files can be found, preserving the record not only of how your image was built, but how it’s meant to be run as a full application.

 类似资料: