赞
踩
Compose 简介
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程。
Compose 使用的三个步骤:
使用 Dockerfile 定义应用程序的环境。
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
最后,执行 docker-compose up 命令来启动并运行整个应用程序。
docker-compose.yml 的配置案例如下(配置参数参考下文):
# yaml 配置实例 version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}Compose 安装
LinuxLinux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:
[root@test ~]# curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 617 0 617 0 0 532 0 --:--:-- 0:00:01 --:--:-- 532 100 15.4M 100 15.4M 0 0 1014k 0 0:00:15 0:00:15 --:--:-- 1409k要安装其他版本的 Compose,请替换 1.24.1。
将可执行权限应用于二进制文件:
[root@test ~]# chmod +x /usr/local/bin/docker-compose [root@test ~]# ll /usr/local/bin/docker-compose -rwxr-xr-x 1 root root 16154160 Dec 24 12:21 /usr/local/bin/docker-compose创建软链:
[root@test ~]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose [root@test ~]#测试是否安装成功:
[root@test ~]# docker-compose --version docker-compose version 1.24.0, build 0aa59064 [root@test ~]#注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
使用
1、准备
创建一个测试目录:
[root@test ~]# mkdir composetest [root@test ~]# cd composetest在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
[root@test composetest]# more app.py import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379。
在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:
[root@test composetest]# more requirements.txt flask redis2、创建 Dockerfile 文件
在 composetest 目录中,创建一个名为的文件 Dockerfile,内容如下:
[root@test composetest]# more Dockerfile FROM python WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN sed -i 's#http://archive.ubuntu.com/#http://mirrors.tuna.tsinghua.edu.cn/#' /etc/apt/sources.list; RUN apt-get update --fix-missing && apt-get install -y gcc musl-dev --fix-missing COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]Dockerfile 内容解释:
- FROM python: 从 Python 映像开始构建镜像。
- WORKDIR /code: 将工作目录设置为 /code。
ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0设置 flask 命令使用的环境变量。
RUN sed -i 's#http://archive.ubuntu.com/#http://mirrors.tuna.tsinghua.edu.cn/#' /etc/apt/sources.list; 这个可不要
- RUN apt-get update --fix-missing && apt-get install -y gcc musl-dev --fix-missing: 更新镜像、安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
COPY requirements.txt requirements.txt RUN pip install -r requirements.txt复制 requirements.txt 并安装 Python 依赖项。
- COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
- CMD ["flask", "run"]: 容器提供默认的执行命令为:flask run。
3、创建 docker-compose.yml
在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
[root@test composetest]# more docker-compose.yml # yaml 配置 version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"该 Compose 文件定义了两个服务:web 和 redis。
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
4、使用 Compose 命令构建和运行您的应用
在测试目录中,执行以下命令来启动应用程序:
[root@test composetest]# docker-compose up Building web Step 1/10 : FROM python ---> b162b5322f1c Step 2/10 : WORKDIR /code ---> Using cache ---> 4a63c53957b3 Step 3/10 : ENV FLASK_APP app.py ---> Using cache ---> 96a5dbfc9ed5 Step 4/10 : ENV FLASK_RUN_HOST 0.0.0.0 ---> Using cache ---> 0db6c7adf367 Step 5/10 : RUN sed -i 's#http://archive.ubuntu.com/#http://mirrors.tuna.tsinghua.edu.cn/#' /etc/apt/sources.list; ---> Using cache ---> a90e4a3a8694 Step 6/10 : RUN apt-get update --fix-missing && apt-get install -y gcc musl-dev --fix-missing ---> Running in 3c34ab282d11 Get:1 http://deb.debian.org/debian buster InRelease [122 kB] Get:2 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB] Get:3 http://deb.debian.org/debian buster-updates InRelease [49.3 kB] Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [167 kB] Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7908 kB] Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [5792 B] Fetched 8317 kB in 8s (1014 kB/s) Reading package lists... Reading package lists... Building dependency tree... Reading state information... gcc is already the newest version (4:8.3.0-1). Recommended packages: linux-musl-dev The following NEW packages will be installed: musl musl-dev 0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded. Need to get 976 kB of archives. After this operation, 4037 kB of additional disk space will be used. Get:1 http://deb.debian.org/debian buster/main amd64 musl amd64 1.1.21-2 [398 kB] Get:2 http://deb.debian.org/debian buster/main amd64 musl-dev amd64 1.1.21-2 [578 kB] debconf: delaying package configuration, since apt-utils is not installed Fetched 976 kB in 1s (801 kB/s) Selecting previously unselected package musl:amd64. (Reading database ... 24526 files and directories currently installed.) Preparing to unpack .../musl_1.1.21-2_amd64.deb ... Unpacking musl:amd64 (1.1.21-2) ... Selecting previously unselected package musl-dev:amd64. Preparing to unpack .../musl-dev_1.1.21-2_amd64.deb ... Unpacking musl-dev:amd64 (1.1.21-2) ... Setting up musl:amd64 (1.1.21-2) ... Setting up musl-dev:amd64 (1.1.21-2) ... Removing intermediate container 3c34ab282d11 ---> 3d454ac0c1a8 Step 7/10 : COPY requirements.txt requirements.txt ---> 2c2a64fc8172 Step 8/10 : RUN pip install -r requirements.txt ---> Running in bbc2048fd41f Collecting flask Downloading https://files.pythonhosted.org/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f43bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl (94kB) Collecting redis Downloading https://files.pythonhosted.org/packages/32/ae/28613a62eea0d53d3db3147f8715f90da07667e99baeedf1010eb400f8c0/redis-3.3.11-py2.py3-none-any.whl (66kB) Collecting click>=5.1 Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB) Collecting Werkzeug>=0.15 Downloading https://files.pythonhosted.org/packages/ce/42/3aeda98f96e85fd26180534d36570e4d18108d62ae36f87694b476b83d6f/Werkzeug-0.16.0-py2.py3-none-any.whl (327kB) Collecting Jinja2>=2.10.1 Downloading https://files.pythonhosted.org/packages/65/e0/eb35e762802015cab1ccee04e8a277b03f1d8e53da3ec3106882ec42558b/Jinja2-2.10.3-py2.py3-none-any.whl (125kB) Collecting itsdangerous>=0.24 Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl Collecting MarkupSafe>=0.23 Downloading https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz Building wheels for collected packages: MarkupSafe Building wheel for MarkupSafe (setup.py): started Building wheel for MarkupSafe (setup.py): finished with status 'done' Created wheel for MarkupSafe: filename=MarkupSafe-1.1.1-cp38-cp38-linux_x86_64.whl size=32305 sha256=78b7c067845464292f66d06a49ed597a561776dd2e23c17504ef313797ec6950 Stored in directory: /root/.cache/pip/wheels/f2/aa/04/0edf07a1b8a5f5f1aed7580fffb69ce8972edc16a505916a77 Successfully built MarkupSafe Installing collected packages: click, Werkzeug, MarkupSafe, Jinja2, itsdangerous, flask, redis Successfully installed Jinja2-2.10.3 MarkupSafe-1.1.1 Werkzeug-0.16.0 click-7.0 flask-1.1.1 itsdangerous-1.1.0 redis-3.3.11 Removing intermediate container bbc2048fd41f ---> 7b8330b3eafb Step 9/10 : COPY . . ---> 0fa9f1c402b5 Step 10/10 : CMD ["flask", "run"] ---> Running in 9f26a37bec7c Removing intermediate container 9f26a37bec7c ---> f9afaf794b16 Successfully built f9afaf794b16 Successfully tagged composetest_web:latest WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Pulling redis (redis:alpine)... alpine: Pulling from library/redis 63bc94deeb28: Pull complete 828e397560e3: Pull complete 5902d88df6c2: Pull complete 157b2c953c6d: Pull complete b5212c16b59d: Pull complete 5f8f01031701: Pull complete Digest: sha256:613ab7e1c0175cae18b69c291512e5e8f1129175f6617ff2126b7ac9a1e5c550 Status: Downloaded newer image for redis:alpine Creating composetest_redis_1 ... done Creating composetest_web_1 ... done Attaching to composetest_redis_1, composetest_web_1 redis_1 | 1:C 24 Dec 2019 07:51:42.303 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 24 Dec 2019 07:51:42.303 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 24 Dec 2019 07:51:42.303 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf redis_1 | 1:M 24 Dec 2019 07:51:42.305 * Running mode=standalone, port=6379. redis_1 | 1:M 24 Dec 2019 07:51:42.305 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. redis_1 | 1:M 24 Dec 2019 07:51:42.305 # Server initialized redis_1 | 1:M 24 Dec 2019 07:51:42.305 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. redis_1 | 1:M 24 Dec 2019 07:51:42.305 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. redis_1 | 1:M 24 Dec 2019 07:51:42.305 * Ready to accept connections web_1 | * Serving Flask app "app.py" web_1 | * Environment: production web_1 | WARNING: This is a development server. Do not use it in a production deployment. web_1 | Use a production WSGI server instead. web_1 | * Debug mode: off web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) web_1 | 192.168.1.252 - - [24/Dec/2019 07:52:25] "GET / HTTP/1.1" 200 - web_1 | 192.168.1.252 - - [24/Dec/2019 07:52:32] "GET / HTTP/1.1" 200 -浏览器访问:
第三次访问:
如果你想在后台执行该服务可以加上 -d 参数:
[root@test composetest]# docker-compose up -d Starting composetest_redis_1 ... done Starting composetest_web_1 ... doneyml 配置指令参考
version
指定本 yml 依从的 compose 哪个版本制定的。
build
指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7" services: webapp: build: ./dir或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
version: "3.7" services: webapp: build: context: ./dir dockerfile: Dockerfile-alternate args: buildno: 1 labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value" target: prod
- context:上下文路径。
- dockerfile:指定构建镜像的 Dockerfile 文件命。
- args:添加构建参数,这是只能在构建过程中访问的环境变量。
- labels:设置构建镜像的标签。
- target:多层构建,可以指定构建哪一层。
cap_add,cap_drop
添加或删除容器拥有的宿主机的内核功能。
cap_add: - ALL # 开启全部权限 cap_drop: - SYS_PTRACE # 关闭 ptrace权限cgroup_parent
为容器指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: m-executor-abcd
command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
container_name
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
depends_on
设置依赖关系。
- docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
- docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
- docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7" services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres注意:web 服务不会等待 redis db 完全启动 之后才启动。
deploy
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
version: "3.7" services: redis: image: redis:alpine deploy: mode:replicated replicas: 6 endpoint_mode: dnsrr labels: description: "This redis service label" resources: limits: cpus: '0.50' memory: 50M reservations: cpus: '0.25' memory: 20M restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s可以选参数:
endpoint_mode:访问集群服务的方式。
endpoint_mode: vip # Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。 endpoint_mode: dnsrr # DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
mode:指定服务提供的模式。
replicated:复制服务,复制指定服务到集群的机器上。
global:全局服务,服务将部署至集群的每个节点。
图解:下图中黄色的方块是 replicated 模式的运行情况,灰色方块是 global 模式的运行情况。
replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
restart_policy:配置如何在退出容器时重新启动容器。
- condition:可选 none,on-failure 或者 any(默认值:any)。
- delay:设置多久之后重启(默认值:0)。
- max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
- window:设置容器重启超时时间(默认值:0)。
rollback_config:配置在更新失败的情况下应如何回滚服务。
- parallelism:一次要回滚的容器数。如果设置为0,则所有容器将同时回滚。
- delay:每个容器组回滚之间等待的时间(默认为0s)。
- failure_action:如果回滚失败,该怎么办。其中一个 continue 或者 pause(默认pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在回滚期间可以容忍的故障率(默认为0)。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认 stop-first )。
update_config:配置应如何更新服务,对于配置滚动更新很有用。
- parallelism:一次更新的容器数。
- delay:在更新一组容器之间等待的时间。
- failure_action:如果更新失败,该怎么办。其中一个 continue,rollback 或者pause (默认:pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在更新过程中可以容忍的故障率。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认stop-first)。
注:仅支持 V3.4 及更高版本。
devices
指定设备映射列表。
devices: - "/dev/ttyUSB0:/dev/ttyUSB0"dns
自定义 DNS 服务器,可以是单个值或列表的多个值。
dns: 8.8.8.8 dns: - 8.8.8.8 - 9.9.9.9dns_search
自定义 DNS 搜索域。可以是单个值或列表。
dns_search: example.com dns_search: - dc1.example.com - dc2.example.comentrypoint
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint: - php - -d - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunitenv_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file: - ./common.env - ./apps/web.env - /opt/secrets.envenvironment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment: RACK_ENV: development SHOW: 'true'expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose: - "3000" - "8000"extra_hosts
添加主机名映射。类似 docker client --add-host。
extra_hosts: - "somehost:162.242.195.82" - "otherhost:50.31.209.229"以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost 50.31.209.229 otherhosthealthcheck
用于检测 docker 服务是否健康运行。
healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序 interval: 1m30s # 设置检测间隔 timeout: 10s # 设置检测超时时间 retries: 3 # 设置重试次数 start_period: 40s # 启动后,多少秒开始启动检测程序image
指定容器运行的镜像。以下格式都可以:
image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd # 镜像idlogging
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file" driver: "syslog" driver: "none"仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging: driver: json-file options: max-size: "200k" # 单个文件大小为200k max-file: "10" # 最多10个文件当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"network_mode
设置网络模式。
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"networks
配置容器连接的网络,引用顶级 networks 下的条目 。
services: some-service: networks: some-network: aliases: - alias1 other-network: aliases: - alias2 networks: some-network: # Use a custom driver driver: custom-driver-1 other-network: # Use a custom driver which takes special options driver: custom-driver-2aliases :同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
restart
- no:是默认的重启策略,在任何情况下都不会重启容器。
- always:容器总是重新启动。
- on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
- unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
restart: "no" restart: always restart: on-failure restart: unless-stopped注:swarm 集群模式,请改用 restart_policy。
secrets
存储敏感数据,例如密码:
version: "3.1" services: mysql: image: mysql environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret secrets: - my_secret secrets: my_secret: file: ./my_secret.txtsecurity_opt
修改容器默认的 schema 标签。
security-opt: - label:user:USER # 设置容器的用户标签 - label:role:ROLE # 设置容器的角色标签 - label:type:TYPE # 设置容器的安全策略标签 - label:level:LEVEL # 设置容器的安全等级标签stop_grace_period
指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
stop_grace_period: 1s # 等待 1 秒 stop_grace_period: 1m30s # 等待 1 分 30 秒默认的等待时间是 10 秒。
stop_signal
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
sysctls
设置容器中的内核参数,可以使用数组或字典格式。
sysctls: net.core.somaxconn: 1024 net.ipv4.tcp_syncookies: 0 sysctls: - net.core.somaxconn=1024 - net.ipv4.tcp_syncookies=0tmpfs
在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
tmpfs: /run tmpfs: - /run - /tmpulimits
覆盖容器默认的 ulimit。
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000volumes
将主机的数据卷或着文件挂载到容器里。
version: "3.7" services: db: image: postgres:latest volumes: - "/localhost/postgres.sock:/var/run/postgres/postgres.sock" - "/localhost/data:/var/lib/postgresql/data"
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。