Docker 架构 | 菜鸟教程
docker由dockerd来接受客户端的命令,它可以下载、管理镜像,创建、管理容器。
由一个镜像可以创建多个容器,系统中运行的虚拟实体,就是容器。
dockerd也可以管理容器与宿主机之间的端口,网络,目录映射。
每个容器由自己的ip吗?是的
容器可以启动,也可以停:docker start/stop
删除正在运行或已停止的容器:docker rm [-f]
进入容器 docker attach 或 nsenter (没试过)
编译:https://www.cnblogs.com/newguy/p/10609765.html
docker相关概念:什么是Docker?看这一篇干货文章就够了! - 知乎 (zhihu.com)
dockerd -- 服务进程
容器 -- 运行的image称为容器
官方教程是理解docker的很好的一个过程https://docs.docker.com/get-started/
看完part1-part10,跟着操作,就能理解dockers关键技术。
启动一个ubuntu镜像,如果没有这个镜像就下载,然后映射宿主机的$(pwd)目录到容器的/src目录,容器启动后,运行bash进程,然后登录进去,如果从bash命令行退出,容器也退出了。
docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
如何进入一个运行的container:
如何进入、退出docker的container_docker 进入container_我是干勾鱼的博客-CSDN博客
查看正在运行的容器:
docker ps
容器的存储空间,默认是临时目录,容器退出存储的内容就丢失了,要想保留容器中修改的数据,就要映射宿主机目录到容器内,有两种映射方法:volume mount和bind mount,经体验,感觉bind mount更好用一些,下面的启动容器命令就是用的bind mount:
docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
一般来说每个container都有自己的一套完整的文件系统,就是说每个container都可以用命令行登录上去,例如,下面的命令登录了mysql容器下面的文件系统:
[root@srcapp10 getting-started-app]# docker exec -it getting-started-app_mysql_1 /bin/bash
bash-4.4# ls /
bin boot dev docker-entrypoint-initdb.d entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
这个登录了我的app容器文件系统,包括了node,yarn等应用程序:
[root@srcapp10 getting-started-app]# docker exec -it getting-started-app_app_1 /bin/ash
/app # ps -ef
PID USER TIME COMMAND
1 root 0:00 node /opt/yarn-v1.22.19/bin/yarn.js run dev
49 root 0:00 /usr/local/bin/node /app/node_modules/.bin/nodemon src/index.js
61 root 0:00 /usr/local/bin/node src/index.js
109 root 0:00 /bin/ash
115 root 0:00 ps -ef
登录容器的文件系统,一般要指定命令行程序:sh/bash/ash 都可以,只要容器的文件系统里有这样命令。
docker exec和docker run是不同的,docker run要指定一个镜像,它会创建这个镜像的容器,然后执行后面的命令,而docker exec是让一个已经运行的容器执行后面的命令,docker exec要指定一个容器名。例如:
docker run perl:5.34.0 perl -Mbignum=bpi -wle "print bpi(200)"
# 以perl:5.34.0创建容器,然后在容器中执行perl -Mbignum=bpi -wle "print bpi(200)"
为了能用docker exec
docker run -d -w /home perl:5.34.0 tail -f /dev/null
# 然后
docker exec flamboyant_johnson perl -Mbignum=bpi -wle "print bpi(200)"
docker compose问题:
没有docker compose这个命令,而是docker-compose,这是一个python程序,用yum可以下载,与官方教程(Use Docker Compose | Docker Docs)不同的是,要注意版本问题,如果docker-compose --version是1.6.0+就要在docker-compose.yml文件里指定version '2',而默认是version '1',另外docker-compose的默认输入文件是当前目录下的docker-compose.yml,因此官方文档中的compose.yaml应该改成docker-compose.yml,而内容应该增加version '2',如下:
version: '2'
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 172.32.148.228:3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todosmysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todosvolumes:
todo-mysql-data:
compose会自动创建docker网络,注意删除旧网络。
创建镜像,除了用Dockerfile,还可以在容器里安装、编译依赖,然后commit,以这种方式固化对容器的修改。
Docker生成镜像的两种方式 - 知乎 (zhihu.com)
关于容器访问外网问题,我试过用openeular的镜像创建的容器,没法访问外网,没法curl百度,或yum,但是用centos-stream-8的镜像创建的容器,是可以访问外网的,可以ping、curl百度,宿主机没有做什么特殊配置,看来这个和镜像有很大关系,openeular的docker镜像真垃圾。
Docker-Bridge Network 02 容器与外部通信 - 云中往事cloud - 博客园 (cnblogs.com)
关于kubebuilder 构建operator
利用 kubebuilder 优化 Kubernetes Operator 开发体验 (dongyueweb.com)
The Operator itself is a piece of software running in a Pod on the cluster, interacting with the Kubernetes API server. That’s how it gets notified about the presence or modification of
FooBarApp
objects. That’s also when it will start running its loop to ensure that the application service is actually available and configured in the way the user expressed in the specification ofFooBarApp
objects. This is called a reconciliation loop
operator会引入一个自定义资源(CRD),就像deployment资源(deployment资源是k8s内置资源,用户只要配置yaml文件就能创建deployment资源),operator引入的CRD也一样。
operator = 自定义controller + CRD
CRD可以独立于controller创建,这样就创建了一种资源,如deployment、pod、replicaSet就是一种资源,还可以创建这种资源的对象。但是样只是数据,没有对资源对象的控制,要想有对资源对象的控制,就要创建controller,controller就是一个pod应用,通过kubernetes API控制资源对象。
见这篇文章,写的很清晰:
了解Operator与CRD的区别与实践 - Layzer - 博客园 (cnblogs.com)
相对于虚机,容器的动态性会更强
一方面,单进程的故障、OOM等都可能会导致容器重启,另一方面,K8s的调度器会根据节点的资源状况进行一定的动态调度。从应对的角度,一方面需要配置数据库应用的调度优先级和资源配给,确保K8s尽可能保证数据库pod的资源;另一方面,对于特定的数据库,可以考虑某些节点只预留给数据库Pod使用。
一个pod里可能会有多个container,如何查看pod里的container名称,有许多办法:
首先创建pod或deployment时可以指定container名。
其次可以用 kubectl describe 查看。
operator其实就是自定义controller+自定义资源,自定义controller就是一个可执行程序,调用client-go库,操作k8s api,controller既可以在k8s集群外执行,也可以作为pod在k8s内执行,通过网络和k8s api,controller可以控制k8s集群和pod里的应用。
在operator里选择deployment里的pod用什么办法呢?用selector,pod的selector也是在定义资源(pod、deployment)时指定的,可以任意指定。
在单机上创建k8s实验环境可以使用kind
kind – Quick Start (k8s.io)
还需单独下载kubectl,这个程序相当于k8s客户端。
在kubernete的源码中有sample-controller例子,这个例子是自定义operator的很好的例子,涉及了代码生成,CRD的编写,controller的编写,这例子生成代码的脚本需要在kubernete源码环境中才能成功,因此不要单独下载sample-controller的代码库进行编译。
community/contributors/devel/controllers.md at 8cafef897a22026d42f5e5bb3f104febe7e29830 · kubernetes/community · GitHub
client-go/examples/workqueue/main.go at master · kubernetes/client-go · GitHub
GitHub - kubernetes/sample-controller: Repository for sample controller. Complements sample-apiserver
Client-go Informer 使用 - 知乎 (zhihu.com)
k8s中label和label selector的基本概念及使用方法 - Zhai_David - 博客园 (cnblogs.com)
k8s之StatefulSet详解-CSDN博客
go - 如何使用 go-client 在 kubernetes 中获取 pod 的状态 - IT工具网 (coder.work)
一文图解Kubernetes的持久化存储解决方案 - 知乎 (zhihu.com)
remotecommand package - k8s.io/client-go/tools/remotecommand - Go Packages
探索client-go中的exec和cp的原理 - 刘达的博客 (imliuda.com)
client-go使用总结一,获取pod状态_51CTO博客_client-go 文档