文章目录
- docker学习第六天
-
- [1. 使用python业务代码构建自己的镜像](#1. 使用python业务代码构建自己的镜像)
-
- 第1步:编辑app.py文件,我们的程序文件--》业务的核心代码程序
- 第2步:编辑requirements.txt文件
- 编写Dockerfile文件
- 第4步:生成镜像文件
- 第5步使用镜像,启动容器
- 第6步:访问容器的web服务
- [第7步: 启动redis容器](#第7步: 启动redis容器)
- [第八步: 再次启动一个自己制作镜像的容器,链接到redis容器](#第八步: 再次启动一个自己制作镜像的容器,链接到redis容器)
- [2. docker compose](#2. docker compose)
-
- [2.1. 什么是compese](#2.1. 什么是compese)
- [2.2. 试一下](#2.2. 试一下)
- [2.3. 涉及到几个命令](#2.3. 涉及到几个命令)
- [3. docker 私有仓库habor](#3. docker 私有仓库habor)
-
- [3.1. 装一个harbor仓库](#3.1. 装一个harbor仓库)
- [4. 使用harbor](#4. 使用harbor)
-
- [4.1. 在harbor里边创建一个用户](#4.1. 在harbor里边创建一个用户)
- [4.2. 传镜像到仓库](#4.2. 传镜像到仓库)
- [5. docker容器的监控](#5. docker容器的监控)
-
- [5.1. 监控的意义是什么](#5.1. 监控的意义是什么)
- [5.2. 监控什么东西?](#5.2. 监控什么东西?)
- [5.3. 监控的全能命令](#5.3. 监控的全能命令)
docker学习第六天
1. 使用python业务代码构建自己的镜像
第1步:编辑app.py文件,我们的程序文件--》业务的核心代码程序
shell
[root@docker-1 Dockerfile]# mkdir /myapp
[root@docker-1 Dockerfile]# cd /myapp/
[root@docker-1 myapp]#
[root@docker-1 myapp]# vim app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/") #zhuang'sh
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
[root@docker-1 myapp]#
当运行这段代码时,它将创建一个简单的 Flask 应用程序,该应用程序可以通过 HTTP 请求提供一个简单的网页。
首先,我们导入了所需的模块。
Flask
模块用于创建和运行 Flask 应用程序,Redis
模块用于连接和与 Redis 数据库进行交互,os
模块用于访问操作系统功能,socket
模块用于获取主机名。接下来,我们创建了一个 Redis 实例,通过指定主机名为 "redis" 来连接到 Redis 数据库。
redis
变量将用于与 Redis 进行交互。我们还设置了连接超时时间为 2 秒,以及套接字超时时间为 2 秒。然后,我们创建了一个 Flask 应用程序实例,并将其存储在
app
变量中。__name__
参数表示当前模块的名称,这在 Flask 中是必需的。接下来,我们定义了一个根路由
/
,它是通过装饰器@app.route()
来实现的。当用户访问根路由时,将执行下面定义的hello()
函数。
hello()
函数首先尝试通过调用redis.incr("counter")
来增加一个名为 "counter" 的计数器的值。redis.incr()
方法将计数器的值加一,并返回新的值。如果连接到 Redis 出现问题,或者在增加计数器时发生错误,将捕获RedisError
异常,并将visits
变量设置为一个字符串 "cannot connect to Redis, counter disabled"。然后,我们定义了一个 HTML 字符串
html
,其中包含了要显示的信息。这个字符串使用了一些占位符,如{name}
、{hostname}
和{visits}
,它们将在后面的.format()
方法中被实际的值替换。最后,我们通过调用
app.run()
方法来运行应用程序。这将启动一个本地的 Web 服务器,监听主机地址为'0.0.0.0'
,端口号为80
。这意味着应用程序将在本地所有可用的 IP 地址上监听传入的请求。当您访问应用程序的根路由时,它将返回一个包含问候语、主机名和访问计数的 HTML 页面。
希望这次的解释更加详细,如果还有任何疑问,请随时提问。
第2步:编辑requirements.txt文件
告诉别人 我需要装哪些库
shell
[root@docker-1 myapp]# vim requirements.txt
Flask
Redis
shell
[root@docker-1 myapp]# pip3 freeze >requirements.txt
[root@docker-1 myapp]# cat requirements.txt
click==8.0.4
dataclasses==0.8
Flask==2.0.3
importlib-metadata==4.8.3
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
typing-extensions==4.1.1
Werkzeug==2.0.3
zipp==3.6.0
[root@docker-1 myapp]#
批量根据requirements.txt文件里的库,开始安装,不需要手工的去指定库名字和版本了,效率比较高
[root@scdocker myapp]# pip3 install -r requirements.txt
因为我们不是开发者的那台测试环境的电脑,所以我们使用vim直接输入需要的库的名字
[root@sc-docker-server mydocker]# vim requirements.txt
Flask
Redis
编写Dockerfile文件
shell
[root@docker-1 myapp]# cat Dockerfile
FROM python:2.7-slim
WORKDIR /app
ADD . /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
ENV AUTHOR cali
CMD ["python","app.py"]
[root@docker-1 myapp]#
这是一个 Dockerfile 文件,用于构建 Docker 镜像。下面是对每个指令的解释:
FROM python:2.7-slim
:这个指令指定了基础镜像,即使用的基础操作系统和软件环境。在这里,基础镜像是python:2.7-slim
,它是一个带有 Python 2.7 的精简版镜像。
WORKDIR /app
:这个指令设置了工作目录为/app
,即在容器内部创建一个名为/app
的目录,并将其设置为当前工作目录。
ADD . /app
:这个指令将当前目录下的所有文件和文件夹复制到容器内部的/app
目录中。
RUN pip install --trusted-host pypi.python.org -r requirements.txt
:这个指令在容器内部执行命令,安装requirements.txt
文件中列出的 Python 依赖包。--trusted-host
参数用于指定信任的主机,这里设置为pypi.python.org
。
EXPOSE 80
:这个指令声明容器将监听的端口号为 80。这并不会自动映射主机和容器的端口,只是为了方便其他人了解容器的预期端口。
ENV NAME World
:这个指令设置了一个环境变量NAME
的值为World
。在容器运行时,可以通过读取这个环境变量来获取相应的值。
ENV AUTHOR cali
:这个指令设置了一个环境变量AUTHOR
的值为cali
。
CMD ["python", "app.py"]
:这个指令指定了容器启动时要执行的命令。在这里,它运行了一个 Python 脚本app.py
。这个 Dockerfile 的作用是构建一个基于 Python 2.7 的镜像,将当前目录下的文件复制到容器内部的
/app
目录中,安装指定的 Python 依赖包,并在容器启动时运行app.py
脚本。
第4步:生成镜像文件
shell
[root@docker-1 myapp]# docker build -t scpyweb:1.0 .
镜像名字为scpyweb 版本为1.0
shell
[root@docker-1 myapp]# docker images|grep scpyweb
scpyweb 1.0 5d06099beec8 35 seconds ago 160MB
[root@docker-1 myapp]#
第5步使用镜像,启动容器
shell
[root@docker-1 myapp]# docker run -d -p 5080:80 --name sc-pyweb-1 scpyweb:1.0
c8ffa1309532bf5856606e2b59f4d703fa208a01c5dde5cf9a72f0b5841d11bb
[root@docker-1 myapp]#
第6步:访问容器的web服务
curl或者chrome浏览器访问 宿主机ip:5080
因为redis数据库容器没有启动,flask web服务不能连接到redis数据库
shell
[root@docker-1 myapp]# docker run -d -p 5080:80 --name sc-pyweb-1 scpyweb:1.0
c8ffa1309532bf5856606e2b59f4d703fa208a01c5dde5cf9a72f0b5841d11bb
[root@docker-1 myapp]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8ffa1309532 scpyweb:1.0 "python app.py" 8 minutes ago Up 8 minutes 0.0.0.0:5080->80/tcp, :::5080->80/tcp sc-pyweb-1
[root@docker-1 myapp]#
第7步: 启动redis容器
shell
[root@docker-1 ~]# docker run -d -p 6379:6379 --name sc-redis-1 redis
5429cac2ac82f11b672817bf65a4aa86c662b733aa47e1ce34cb74c096ccf664
[root@docker-1 ~]#
第八步: 再次启动一个自己制作镜像的容器,链接到redis容器
shell
[root@docker-1 ~]# docker run -d -p 5082:80 --name sc-pyweb-2 --link sc-redis-1:redis scpyweb:1.0
39405e74a75ad7aa71f8a3b497c5b72dffdf594360b24cf3d3d71992ab1e6c6e
[root@docker-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
39405e74a75a scpyweb:1.0 "python app.py" 8 seconds ago Up 8 seconds 0.0.0.0:5082->80/tcp, :::5082->80/tcp sc-pyweb-2
2. docker compose
2.1. 什么是compese
作用
:批量去启动容器容器编排
- 同时启动很多容器---->批量
- 启动容器有顺序
- 编排:有计划的(编着顺序的)安排
缺点
只能在一台机器上编排
2.2. 试一下
shell
[root@docker-1 docker-mysql]# cat compose.yaml
services:
db:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10.6.4-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
[root@docker-1 docker-mysql]#
当你运行
docker-compose up
命令时,Docker Compose 将会读取配置文件,并根据配置文件中的定义启动和管理多个容器。它会自动创建网络、卷等资源,并按照定义的顺序启动容器。
shell
[root@docker-1 docker-mysql]# docker compose up -d
[root@docker-1 docker-mysql]# docker compose ls
NAME STATUS CONFIG FILES
docker-mysql running(2) /docker-mysql/compose.yaml
[root@docker-1 docker-mysql]#
shell
[root@docker-1 docker-mysql]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
docker-mysql-db-1 mariadb:10.6.4-focal "docker-entrypoint.s..." db 5 minutes ago Up 5 minutes 3306/tcp, 33060/tcp
docker-mysql-wordpress-1 wordpress:latest "docker-entrypoint.s..." wordpress 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp
[root@docker-1 docker-mysql]#
2.3. 涉及到几个命令
docker compose up -d
docker-compose up
用于启动docker-compose.yml
文件中定义的服务。-d
选项表示"分离"模式,这意味着服务将在后台运行,使你能够继续使用同一终端会话执行其他命令。- docker compose stop 可以用来停止
docker compose ls
用于列出当前目录下的所有 Docker Compose 项目。
docker compose ps
用于显示当前 Docker Compose 项目中所有服务的状态。
3. docker 私有仓库habor
容器最重要的三个概念
- 镜像
- 仓库
- 容器
仓库分为私有 和 公共
私有最出名的是:
harbor
nexus 也很好--->内置了很多的镜像
3.1. 装一个harbor仓库
https://github.com/goharbor/harbor/releases/tag/v2.1.0 先去官网下载2.1的版本
shell
'新建harbor文件夹,放进去解压'
[root@docker-1 Dockerfile] mkdir /harbor
[root@docker-1 Dockerfile] cd /harbor/
[root@docker-1 harbor] tar xf harbor-offline-installer-v2.1.0.tgz
[root@docker-1 harbor]# ls
harbor harbor-offline-installer-v2.1.0.tgz
[root@docker-1 harbor]# cd harbor
[root@docker-1 harbor]# ls
common.sh harbor.v2.1.0.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
[root@docker-1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@docker-1 harbor]#
shell
'修改 harbor.yml 中的hostname和prot 注释掉 https(简化)'
然后拖拽docker compose这个软件进入当前目录,并且加入可执行权限
shell
[root@docker-1 harbor]# chmod +x docker-compose
[root@docker-1 harbor]# cp docker-compose /usr/bin/
[root@docker-1 harbor]#
为什么拷贝到 /usr/bin 是因为在环境变量中可以找到
shell
'然后执行:'
[root@docker-1 harbor]# ./install.sh
shell
'查看是否成功'
[root@docker-1 harbor]# docker compose ls
NAME STATUS CONFIG FILES
harbor running(9) /harbor/harbor/docker-compose.yml
[root@docker-1 harbor]#
[root@docker-1 harbor]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
harbor-core goharbor/harbor-core:v2.1.0 "/harbor/entrypoint...." core 5 minutes ago Up 5 minutes (healthy)
harbor-db goharbor/harbor-db:v2.1.0 "/docker-entrypoint...." postgresql 5 minutes ago Up 5 minutes (healthy)
harbor-jobservice goharbor/harbor-jobservice:v2.1.0 "/harbor/entrypoint...." jobservice 5 minutes ago Up 5 minutes (healthy)
harbor-log goharbor/harbor-log:v2.1.0 "/bin/sh -c /usr/loc..." log 5 minutes ago Up 5 minutes (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal goharbor/harbor-portal:v2.1.0 "nginx -g 'daemon of..." portal 5 minutes ago Up 5 minutes (healthy)
nginx goharbor/nginx-photon:v2.1.0 "nginx -g 'daemon of..." proxy 5 minutes ago Up 5 minutes (healthy) 0.0.0.0:8089->8080/tcp, :::8089->8080/tcp
redis goharbor/redis-photon:v2.1.0 "redis-server /etc/r..." redis 5 minutes ago Up 5 minutes (healthy)
registry goharbor/registry-photon:v2.1.0 "/home/harbor/entryp..." registry 5 minutes ago Up 5 minutes (healthy)
registryctl goharbor/harbor-registryctl:v2.1.0 "/home/harbor/start...." registryctl 5 minutes ago Up 5 minutes (healthy)
[root@docker-1 harbor]#
搭建成功
账号:admin
密码:Harbor12345
很成功
4. 使用harbor
4.1. 在harbor里边创建一个用户
先创建一个项目
账号:gao
密码: Sc123456
然后得在项目中添加成员
利用gao的用户登录
4.2. 传镜像到仓库
准备一台新的docker虚拟机
修改:daemon.json 文件
添加一行: 对应的ip和端口是 harbor的那台虚拟机
shell
[root@docker-2 docker]# cat daemon.json
{
"registry-mirrors": ["https://naxm4z64.mirror.aliyuncs.com"],
"insecure-registries" : ["192.168.182.166:8089"]
}
[root@docker-2 docker]#
shell
[root@docker-2 docker]# systemctl daemon-reload #刷新服务
[root@docker-2 docker]# systemctl restart docker #刷新docker服务
[root@docker-2 docker]#
shell
[root@docker-2 ~]# docker tag scpyweb:1.0 192.168.182.166:8089/sanchuang/scpyweb:1.0
[root@docker-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.182.166:8089/sanchuang/scpyweb 1.0 5d06099beec8 41 hours ago 160MB
scpyweb 1.0 5d06099beec8 41 hours ago 160MB
nginx latest 605c77e624dd 2 years ago 141MB
[root@docker-2 ~]#
登录私有仓库
shell
[root@docker-2 ~]# docker login 192.168.182.166:8089
Username: gao
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker-2 ~]#
推镜像
shell
[root@docker-2 ~]# docker push 192.168.182.166:8089/sanchuang/scpyweb:1.0
The push refers to repository [192.168.182.166:8089/sanchuang/scpyweb]
cb74c9fb387b: Pushed
e93d0cb48f75: Pushed
8c1272e2c660: Pushed
7a287aad297b: Pushed
7ea2b60b0a08: Pushed
568944187d93: Pushed
b60e5c3bcef2: Pushed
1.0: digest: sha256:6c6d2510b6dd32583c27d4e69ffaf8ca2c0bfcdcb34cc6232987b0a9c854db87 size: 1788
[root@docker-2 ~]#
shell
'试试'
[root@docker-2 ~]# docker tag busybox:latest 192.168.182.166:8089/sanchuang/busybox:latest
[root@docker-2 ~]# docker push 192.168.182.166:8089/sanchuang/busybox
Using default tag: latest
The push refers to repository [192.168.182.166:8089/sanchuang/busybox]
01fd6df81c8e: Pushed
latest: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527
[root@docker-2 ~]#
拉取镜像
shell
[root@docker-2 ~]# docker pull 192.168.182.166:8089/sanchuang/busybox
Using default tag: latest
latest: Pulling from sanchuang/busybox
Digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Status: Downloaded newer image for 192.168.182.166:8089/sanchuang/busybox:latest
192.168.182.166:8089/sanchuang/busybox:latest
[root@docker-2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.182.166:8089/sanchuang/scpyweb 1.0 5d06099beec8 41 hours ago 160MB
scpyweb 1.0 5d06099beec8 41 hours ago 160MB
192.168.182.166:8089/sanchuang/busybox latest beae173ccac6 2 years ago 1.24MB
busybox latest beae173ccac6 2 years ago 1.24MB
nginx latest 605c77e624dd 2 years ago 141MB
[root@docker-2 ~]#
使用拉取下来的镜像
shell
[root@docker-2 ~]# docker run -it --rm --name mybusybox-1 192.168.182.166:8089/sanchuang/busybox
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
5. docker容器的监控
5.1. 监控的意义是什么
提前发现问题,将问题消灭在萌芽状态,防止重大事故的发生
5.2. 监控什么东西?
容器的使用情况--》消耗了多少cpu、内存、磁盘IO、网络IO等情况 --》docker stats
运行容器的宿主机的cpu、内存、磁盘IO、网络IO等情况 --->得到数据
5.3. 监控的全能命令
- dstat
- glances
shell
[root@docker-1 ~]# dstat -am
Terminal width too small, trimming output.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-->
usr sys idl wai hiq siq| read writ| recv send| in out | int csw >
0 0 100 0 0 0| 46k 149k| 0 0 | 3B 15B| 358 575 >
0 0 100 0 0 0| 0 0 |2618B 3456B| 0 0 | 383 534 >
0 0 100 0 0 0| 0 0 |9012B 9298B| 0 0 | 482 705 >^C
[root@docker-1 ~]#
详细监控请看下一节: cAdvisor+Prometheus+Grafana 10分钟搞定Docker容器监控平台