Go猜想录
大道至简,悟者天成
docker基本使用2

初识docker

# 查看版本并顺便检查docker server正常启动,cli可以连接到engine
$ docker version

# 查看engine的一些配置项
$ docker info

# 查看docker command line structure
# docker command的格式,为了解决激增的命令数量难以记忆的问题,推出Management Commands模式
# 1. 使用Management Commands: docker <command> <sub-command> (options)
# 2. 使用Commands: docker <command> (options)
$ docker
# 例子,如下两种模式的命令目的是一样的
$ docker container run
$ docker run

创建一个Nginx服务器

  1. Downloaded image nginx from Docker Hub
  2. Started a new container from that image
  3. Opened port 80 on the host IP
  4. Routes that traffic to the container IP, port 80
# --publish(or -p) 是一种映射host port到container port的方法
$ docker container run --publish 80:80 nginx

# 在后台运行
# 可以使用docker container run --help查看更多详细内容
$ docker container run --publish 80:80 --detach nginx

# docker ps亦可
$ docker container ls

# 停止容器但不删除
# docker stop亦可
$ docker container stop 690

# docker container run总是开启一个新的容器
# docker container start是开启一个已经存在的停止的容器
$ docker container start 690

$ docker container ls

$ docker container ls -a

# 在不手动设置容器名称的情况下docker会随机生成一个adj+n的名称
# detail: https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go
$ docker container run --publish 80:80 --detach --name webhost nginx

$ docker container ls -a

# docker logs亦可
$ docker container logs webhost

$ docker container top

# Display the running processes of a container
$ docker container top webhost

$ docker container --help

$ docker container ls -a

# docker rm亦可
$ docker container rm 63f 690 ode

$ docker container ls

# docker为了防止误操作,不能直接删除一个运行的容器,除非加参数`-f`强制删除
$ docker container rm -f 63f

$ docker container ls -a

docker container run背后的动作

docker container run nginx为例:

  1. Looks for that image locally in image cache, doesn’t find anything
  2. Then looks in remote image repository (defaults to Docker Hub)
  3. Downloads the latest version (nginx:latest by default)
  4. Creates new container based on that image and prepares to start
  5. Gives it a virtual IP on a private network inside docker engine
  6. Opens up port 80 on host and forwards to port 80 in container
  7. Starts container by using the CMD in the image Dockerfile

简单的命令背后docker帮我们做了很多默认的工作,实际上它是高度定制化的,我们可以根据需要进行修改

docker container run –publish 8080:80 –name webhost -d nginx:1.11 nginx -T

如上所示,我们修改了host监听的端口为8080,修改了镜像版本为1.11,修改了开启容器时的CMD命令

container是个什么东西

本质上一个运行着的容器只是资源受限的进程,当进程结束了container也就退出了,如下是在linux环境下的实验结果:

# ubuntu20.04
lucas@ubuntu:~$ docker run --name mongo -d mongo
4137bf48c62bb2230f717c5d2077419b1dc93ce05cd3db414f81c0aa4262bdac
lucas@ubuntu:~$ docker ps
CONTAINER ID   IMAGE    COMMAND                  CREATED          STATUS          PORTS        NAMES
4137bf48c62b   mongo    "docker-entrypoint.s…"   26 seconds ago   Up 25 seconds   27017/tcp    mongo
lucas@ubuntu:~$ ps aux | grep mongo
systemd+ 3800614  0.8  2.7 1538116 112280 ?      Ssl  15:29   0:01 mongod --bind_ip_all
lucas    3801103  0.0  0.0   6300   736 pts/0    S+   15:31   0:00 grep --color=auto mongo
lucas@ubuntu:~$ docker rm -f mongo
mongo
lucas@ubuntu:~$ ps aux | grep mongo
lucas    3801302  0.0  0.0   6300   676 pts/0    S+   15:32   0:00 grep --color=auto mongo

mac环境上略有不同,docker engine实际上是运行在基于xhyve VM上的一个Alpine Linux,我们进入到这个docker VM中才能看到具体运行着的进程

# macOS Big Sur on M1 chip 
$ docker run --name mongo -d mongo 
4ce052bde09ce12cef9856e270347c549b988483fdc86051ee7a6cf409b6d15b
$ docker run --name mongo -d mongo 
$ docker run -it --rm --privileged --pid=host justincormack/nsenter1
/ # ps aux | grep mongo
 2551 999       0:00 mongod --bind_ip_all
 2712 root      0:00 grep mongo
$ docker rm -f mongo  
mongo
$ docker run -it --rm --privileged --pid=host justincormack/nsenter1 
/ #  ps aux | grep mongo
 2839 root      0:00 grep mongo

Lab: 管理多个container

# mysql官方镜像暂不支持arm64,只支持x86_64,所以换用mysql/mysql-server镜像
# uname -a 查看架构
$ docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql/mysql-server
# 查看mysql生成的密码
$ docker logs db
$ docker container run -d --name webserver -p 8080:80 httpd
$ docker container run -d --name proxy -p 80:80 nginx
$ docker ps
# clean up
# 直接使用官方推出的自动补全功能,非常好用(tab completion)
# https://docs.docker.com/compose/completion/
$ docker container stop webserver proxy db
$ docker container rm webserver proxy db
$ docker ps -a

查看container状态的几个命令

# process list in one container
$ docker container top

# details of one container config
$ docker container inspect

# performance stats for all containers
$ docker container stats

进入一个container

# -i keep session open to receive terminal input
# -t simulates a real terminal, like what ssh dose
# 修改开启容器时的CMD命令为bash,结合-it的OPTIONS,直接进入到对应镜像的bash环境中
$ docker container run -it --name nginx nginx bash
# 当我们退出bash的同时容器就相应的停止了,因为我们修改了"Cmd"为bash

# 重新进入上面已经停止的容器的bash中
# docker start --help
$ docker start -ai nginx

# 进入一个已经运行着其他命令的容器的shell
# 例如mysql
$ docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql/mysql-server
$ docker exec -it mysql bash
# 但此时我们退出bash的时候容器并不会停止,因为"exec"基于已有的容器运行在另外一个进程中,并不会影响mysql daemon所在的主进程
-t simulates a real terminal,like what ssh dose
-i keep session open to receive terminal input

References

## Container VS. VM: It's Just a Process

$ docker run --name mongo -d mongo

$ docker ps

$ docker top mongo

$ docker stop mongo

$ docker ps

$ docker top mongo

$ docker start mongo

$ docker ps

$ docker top mongo

## Assignment Answers: Manage Multiple Containers

$ docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes MYSQL_RANDOM_ROOT_PASSWORD

$ docker container logs db

$ docker container run -d --name webserver -p 8080:80 httpd

$ docker ps

$ docker container run -d --name proxy -p 80:80 nginx

$ docker ps

$ docker container ls

$ docker container stop TAB COMPLETION

$ docker ps -a

$ docker container ls -a

$ docker container rm

$ docker ps -a

$ docker image ls

## What's Going On In Containers: CLI Process Monitoring

$ docker container run -d --name nginx nginx

$ docker container run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql

$ docker container ls

$ docker container top mysql

$ docker container top nginx

$ docker container inspect mysql

$ docker container stats --help

$ docker container stats

$ docker container ls

## Getting a Shell Inside Containers: No Need for SSH

$ docker container run -help

$ docker container run -it --name proxy nginx bash

$ docker container ls

$ docker container ls -a

$ docker container run -it --name ubuntu ubuntu

$ docker container ls

$ docker container ls -a

$ docker container start --help

$ docker container start -ai ubuntu

$ docker container exec --help

$ docker container exec -it mysql bash

$ docker container ls

$ docker pull alpine

$ docker image ls

$ docker container run -it alpine bash

$ docker container run -it alpine sh

## $ docker Networks: Concepts for Private and Public Comms in Containers

$ docker container run -p 80:80 --name webhost -d nginx

$ docker container port webhost

$ docker container inspect --format '{{ .NetworkSettings.IPAddress }}' webhost

## $ docker Networks: CLI Management of Virtual Networks

$ docker network ls

$ docker network inspect bridge

$ docker network ls

$ docker network create my_app_net

$ docker network ls

$ docker network create --help

$ docker container run -d --name new_nginx --network my_app_net nginx

$ docker network inspect my_app_net

$ docker network --help

$ docker network connect

$ docker container inspect TAB COMPLETION

$ docker container disconnect TAB COMPLETION

$ docker container inspect

## $ docker Networks: DNS and How Containers Find Each Other

$ docker container ls

$ docker network inspect TAB COMPLETION

$ docker container run -d --name my_nginx --network my_app_net nginx

$ docker container inspect TAB COMPLETION

$ docker container exec -it my_nginx ping new_nginx

$ docker container exec -it new_nginx ping my_nginx

$ docker network ls

$ docker container create --help

## Assignment Answers: Using Containers for CLI Testing

$ docker container run --rm -it centos:7 bash

$ docker ps -a

$ docker container run --rm -it ubuntu:14.04 bash

$ docker ps -a

## Assignment Answers: DNS Round Robin Testing

$ docker network create dude

$ docker container run -d --net dude --net-alias search elasticsearch:2

$ docker container ls

$ docker container run --rm -- net dude alpine nslookup search

$ docker container run --rm --net dude centos curl -s search:9200

$ docker container ls

$ docker container rm -f TAB COMPLETION


20210918 中秋计划

  • Stanford CS107补上反码补码
  • mit-6.033补上网络协议啥的
  • traefik看完
  • go网络看完
  • ai教Lecture 1: Overview | Stanford CS221: AI (Autumn 2019)

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。