zoukankan      html  css  js  c++  java
  • CKA-docker 容器的管理

     

    容器的生命期的问题

    -i 交互

    -t 终端

    -d 守护进程(后台运行)

    -e 指定变量

    --rm  临时容器            --restart=always 不能同时使用

    --name 指定容器名

    # 进入容器

    docker attach <容器ID>

     

    docker run -dit --name=c1 --restart=always  hub.c.163.com/library/centos

    # 查看容器信息

    docker inspect c1

    docker top <容器名> 

    # 读取容器里面的输出 

    docker logs <容器名>

    # 在容器mysql镜像,指定了一个变量

     # 额外的打开一个bash进程

     # 冒号左边是物理机,冒号右边是容器

    • docker exec <容器名> 命令
    • docker start <容器名>
    • docker stop <容器名>
    • docker restrart <容器名>
    • docker top <容器名>
    • docker logs -f <容器名>
    • docker inspect <容器名> 
    • docker cp <拷贝的文件> <容器名>:<目录>           docker cp <容器名>:<目录> <物理机存放地址>  # 容器之间不能这样拷贝

     

      weavescope  工具安装测试

    容器监控工具WeaveScope

    github开源项目地址

    curl -L git.io/scope -o /usr/local/bin/scope

    赋予可执行权限:

    chmod a+x /usr/local/bin/scope

    启动scope:

    scope launch

     

      

    数据卷的使用

    -v /dir                  # 默认指定一个目录,是容器里面的目录。物理机是随机生成一个目录

    -v /dir2:dir           # 冒号左边是物理机里面的目录,冒号右边的是容器目录

    -v /dir2:/dir:rw    # 默认

    -v /dir2:/dir:ro  # 需要手动指定只读

    你得去理解容器里的存储信息(比如:mysql本身存放在哪里的)

    # 需要自己再熟悉下 apache tomcat redis

     

     

    docker网络管理

    # 查看容器ip地址

      

     # 查看本地网桥

    docker network list

    # 查看网络属性

    docker network inspect bridge

    # 会生成docker0

      

    # 自己创建一个网桥

    docker network create -d bridge --subnet=x.x.x.x/24 <网桥名>

     PS: 如何自己通过命令查询 创建网络命令

    容器网络里面有

    bridge  网桥 相当于nat

    host   直接变成主机网络

    none 不设置网络(单独配合一些工具可以变成桥接模式,设置独立IP地址) 

    # 加入到自己的创建的网桥

    # 查看应用所需要的变量,例如wordpress

    PS:可以使用hub或者163里面的 how to use 来看下所需的变量意思

    网易:https://c.163yun.com/hub#/home

    # 查找docker 所有相关帮助命令

    man -k docker

    # 新建一个数据库,使用了两个变量(一个是设置root密码,一个是创建数据库)

      

    # 创建wordpress (正常方式)

      

    # 查看更详细的信息

    docker history  --no-trunc  

     # 再次新建后使用 --link 别名 来省略一些变量参数,并且防止容器内部IP变化导致的配置文件修改  【这部分需要进行试验一下】

     

      

    自定义镜像

    构建镜像:并非是从0到1的过程,在一个已经存在的镜像的基础上,进行构建出新的镜像

    基镜像,基础镜像

    最底层的---是一个干净的操作系统,一般是由厂商来提供

    Dockefile

    #############

    RUN

    ADD

    ENV 

    VOLUME

    CMD

    #############

    # 通过dockerfile 生成容器

    1. 生成临时容器,执行dockerfile 内容,产生容器,最后删除临时容器

     Dockefile 文件举例:

    tar tf  <tar> 查看tar包里面内容

    docker build -t centos:v0 .

    . 当前目录去找(其他目录就用-f [dockerfile文件名],不跟文件名,默认寻找Dockerfile)

    ADD 和 COPY 区别 (需实验)

     add 可以解压,copy 直接复制包(不带解压功能) 
    PS: 目前已知能直接解压的有tar,tar.gz 

    自己搭建一个nginx 镜像

    # 可以自己修改nginx配置文件

     # 守护进程模式开启的方法, docker history  --no-trunc  | tail -2 

     EXPOSE 仅仅是个标识 <--- 告诉别人你默认用的端口是什么

    # 如何判断 CMD 后面需要填写的守护进程参数(需要根据经验,或者找一个镜像通过docker histroy查看)

    Nginx:

    CMD ["nginx", "-g", "daemon off;"]

    SSH:

    CMD["sshd", "-D"]

    Mysql:

    CMD ["mysqld"]

    Centos:

    CMD ["/bin/bash"]

    # ENV 和 用户添加

    ENV

    USER

    # Dockerfile RUN 尽量放在一行来写,会减少镜像层数,从而减小镜像的大小

    # 在dockerfile 里面指定用户执行进程,并设置变量 aa

    # 如果创建的进程是普通用户,想用root进入  docker exec -it -uroot .....的方式

    # VOLUME 定义卷

    VOLUME ["dir1", "dir2"]

    # ssh 的dockerfile 是如何一步步做出这个文件的

      

    私有仓库 

    # 搭建自己的私有仓库

    1. registry

    2. harbor

     使用registry 搭建私有仓库

    registry  端口5000

    /var/lib/registry

    1. 仅允许https 方式访问 

    http+ssl -- tls(传输层的加密)

    两种只能选一种,不要都使用

    # 方法一:

    修改 不适用https 的方式,都需要修改

    /etc/docker/daemon.json

     # 方法二:

     

      

     

     # 从客户端推送镜像到私有仓库

    # 修改tag

     # 再进行推送(推送的时候一定要注意镜像tag是不是复核规范

     #使用curl命令查询的镜像数量

    # 查询镜像的版本

     

    使用脚本来实现查询镜像和版本

    # 老师的脚本,仅供参考

     1 #!/bin/bash
     2 file=$(mktemp)
     3 curl -s $1:5000/v2/_catalog | jq | egrep -v '{|}|[|]' | awk -F" '{print $2}' > $file
     4 while read aa ; do
     5 tag=($(curl -s $1:5000/v2/$aa/tags/list | jq | egrep -v '{|}|[|]|name' | awk -F" '{print $2}'))
     6     for i in ${tag[*]} ; do
     7       echo $1:5000/${aa}:$i
     8     done
     9 done < $file
    10 rm -rf $file
    View Code

    # 用脚本查询结果

    # 删除私有仓库下面多余或无用的镜像

    用老师的PY脚本

    #!/usr/bin/env python
    """
    Usage:
    Shut down your registry service to avoid race conditions and possible data loss
    and then run the command with an image repo like this:
    delete_docker_registry_image.py --image awesomeimage --dry-run
    """
    
    import argparse
    import json
    import logging
    import os
    import sys
    import shutil
    import glob
    
    logger = logging.getLogger(__name__)
    
    
    def del_empty_dirs(s_dir, top_level):
        """recursively delete empty directories"""
        b_empty = True
    
        for s_target in os.listdir(s_dir):
            s_path = os.path.join(s_dir, s_target)
            if os.path.isdir(s_path):
                if not del_empty_dirs(s_path, False):
                    b_empty = False
            else:
                b_empty = False
    
        if b_empty:
            logger.debug("Deleting empty directory '%s'", s_dir)
            if not top_level:
                os.rmdir(s_dir)
    
        return b_empty
    
    
    def get_layers_from_blob(path):
        """parse json blob and get set of layer digests"""
        try:
            with open(path, "r") as blob:
                data_raw = blob.read()
                data = json.loads(data_raw)
                if data["schemaVersion"] == 1:
                    result = set([entry["blobSum"].split(":")[1] for entry in data["fsLayers"]])
                else:
                    result = set([entry["digest"].split(":")[1] for entry in data["layers"]])
                    if "config" in data:
                        result.add(data["config"]["digest"].split(":")[1])
                return result
        except Exception as error:
            logger.critical("Failed to read layers from blob:%s", error)
            return set()
    
    
    def get_digest_from_blob(path):
        """parse file and get digest"""
        try:
            with open(path, "r") as blob:
                return blob.read().split(":")[1]
        except Exception as error:
            logger.critical("Failed to read digest from blob:%s", error)
            return ""
    
    
    def get_links(path, _filter=None):
        """recursively walk `path` and parse every link inside"""
        result = []
        for root, _, files in os.walk(path):
            for each in files:
                if each == "link":
                    filepath = os.path.join(root, each)
                    if not _filter or _filter in filepath:
                        result.append(get_digest_from_blob(filepath))
        return result
    
    
    class RegistryCleanerError(Exception):
        pass
    
    
    class RegistryCleaner(object):
        """Clean registry"""
    
        def __init__(self, registry_data_dir, dry_run=False):
            self.registry_data_dir = registry_data_dir
            if not os.path.isdir(self.registry_data_dir):
                raise RegistryCleanerError("No repositories directory found inside " 
                                           "REGISTRY_DATA_DIR '{0}'.".
                                           format(self.registry_data_dir))
            self.dry_run = dry_run
    
        def _delete_layer(self, repo, digest):
            """remove blob directory from filesystem"""
            path = os.path.join(self.registry_data_dir, "repositories", repo, "_layers/sha256", digest)
            self._delete_dir(path)
    
        def _delete_blob(self, digest):
            """remove blob directory from filesystem"""
            path = os.path.join(self.registry_data_dir, "blobs/sha256", digest[0:2], digest)
            self._delete_dir(path)
    
        def _blob_path_for_revision(self, digest):
            """where we can find the blob that contains the json describing this digest"""
            return os.path.join(self.registry_data_dir, "blobs/sha256",
                                digest[0:2], digest, "data")
    
        def _blob_path_for_revision_is_missing(self, digest):
            """for each revision, there should be a blob describing it"""
            return not os.path.isfile(self._blob_path_for_revision(digest))
    
        def _get_layers_from_blob(self, digest):
            """get layers from blob by digest"""
            return get_layers_from_blob(self._blob_path_for_revision(digest))
    
        def _delete_dir(self, path):
            """remove directory from filesystem"""
            if self.dry_run:
                logger.info("DRY_RUN: would have deleted %s", path)
            else:
                logger.info("Deleting %s", path)
                try:
                    shutil.rmtree(path)
                except Exception as error:
                    logger.critical("Failed to delete directory:%s", error)
    
        def _delete_from_tag_index_for_revision(self, repo, digest):
            """delete revision from tag indexes"""
            paths = glob.glob(
                os.path.join(self.registry_data_dir, "repositories", repo,
                             "_manifests/tags/*/index/sha256", digest)
            )
            for path in paths:
                self._delete_dir(path)
    
        def _delete_revisions(self, repo, revisions, blobs_to_keep=None):
            """delete revisions from list of directories"""
            if blobs_to_keep is None:
                blobs_to_keep = []
            for revision_dir in revisions:
                digests = get_links(revision_dir)
                for digest in digests:
                    self._delete_from_tag_index_for_revision(repo, digest)
                    if digest not in blobs_to_keep:
                        self._delete_blob(digest)
    
                self._delete_dir(revision_dir)
    
        def _get_tags(self, repo):
            """get all tags for given repository"""
            path = os.path.join(self.registry_data_dir, "repositories", repo, "_manifests/tags")
            if not os.path.isdir(path):
                logger.critical("No repository '%s' found in repositories directory %s",
                                 repo, self.registry_data_dir)
                return None
            result = []
            for each in os.listdir(path):
                filepath = os.path.join(path, each)
                if os.path.isdir(filepath):
                    result.append(each)
            return result
    
        def _get_repositories(self):
            """get all repository repos"""
            result = []
            root = os.path.join(self.registry_data_dir, "repositories")
            for each in os.listdir(root):
                filepath = os.path.join(root, each)
                if os.path.isdir(filepath):
                    inside = os.listdir(filepath)
                    if "_layers" in inside:
                        result.append(each)
                    else:
                        for inner in inside:
                            result.append(os.path.join(each, inner))
            return result
    
        def _get_all_links(self, except_repo=""):
            """get links for every repository"""
            result = []
            repositories = self._get_repositories()
            for repo in [r for r in repositories if r != except_repo]:
                path = os.path.join(self.registry_data_dir, "repositories", repo)
                for link in get_links(path):
                    result.append(link)
            return result
    
        def prune(self):
            """delete all empty directories in registry_data_dir"""
            del_empty_dirs(self.registry_data_dir, True)
    
        def _layer_in_same_repo(self, repo, tag, layer):
            """check if layer is found in other tags of same repository"""
            for other_tag in [t for t in self._get_tags(repo) if t != tag]:
                path = os.path.join(self.registry_data_dir, "repositories", repo,
                                    "_manifests/tags", other_tag, "current/link")
                manifest = get_digest_from_blob(path)
                try:
                    layers = self._get_layers_from_blob(manifest)
                    if layer in layers:
                        return True
                except IOError:
                    if self._blob_path_for_revision_is_missing(manifest):
                        logger.warn("Blob for digest %s does not exist. Deleting tag manifest: %s", manifest, other_tag)
                        tag_dir = os.path.join(self.registry_data_dir, "repositories", repo,
                                               "_manifests/tags", other_tag)
                        self._delete_dir(tag_dir)
                    else:
                        raise
            return False
    
        def _manifest_in_same_repo(self, repo, tag, manifest):
            """check if manifest is found in other tags of same repository"""
            for other_tag in [t for t in self._get_tags(repo) if t != tag]:
                path = os.path.join(self.registry_data_dir, "repositories", repo,
                                    "_manifests/tags", other_tag, "current/link")
                other_manifest = get_digest_from_blob(path)
                if other_manifest == manifest:
                    return True
    
            return False
    
        def delete_entire_repository(self, repo):
            """delete all blobs for given repository repo"""
            logger.debug("Deleting entire repository '%s'", repo)
            repo_dir = os.path.join(self.registry_data_dir, "repositories", repo)
            if not os.path.isdir(repo_dir):
                raise RegistryCleanerError("No repository '{0}' found in repositories "
                                           "directory {1}/repositories".
                                           format(repo, self.registry_data_dir))
            links = set(get_links(repo_dir))
            all_links_but_current = set(self._get_all_links(except_repo=repo))
            for layer in links:
                if layer in all_links_but_current:
                    logger.debug("Blob found in another repository. Not deleting: %s", layer)
                else:
                    self._delete_blob(layer)
            self._delete_dir(repo_dir)
    
        def delete_repository_tag(self, repo, tag):
            """delete all blobs only for given tag of repository"""
            logger.debug("Deleting repository '%s' with tag '%s'", repo, tag)
            tag_dir = os.path.join(self.registry_data_dir, "repositories", repo, "_manifests/tags", tag)
            if not os.path.isdir(tag_dir):
                raise RegistryCleanerError("No repository '{0}' tag '{1}' found in repositories "
                                           "directory {2}/repositories".
                                           format(repo, tag, self.registry_data_dir))
            manifests_for_tag = set(get_links(tag_dir))
            revisions_to_delete = []
            blobs_to_keep = []
            layers = []
            all_links_not_in_current_repo = set(self._get_all_links(except_repo=repo))
            for manifest in manifests_for_tag:
                logger.debug("Looking up filesystem layers for manifest digest %s", manifest)
    
                if self._manifest_in_same_repo(repo, tag, manifest):
                    logger.debug("Not deleting since we found another tag using manifest: %s", manifest)
                    continue
                else:
                    revisions_to_delete.append(
                        os.path.join(self.registry_data_dir, "repositories", repo,
                                     "_manifests/revisions/sha256", manifest)
                    )
                    if manifest in all_links_not_in_current_repo:
                        logger.debug("Not deleting the blob data since we found another repo using manifest: %s", manifest)
                        blobs_to_keep.append(manifest)
    
                    layers.extend(self._get_layers_from_blob(manifest))
    
            layers_uniq = set(layers)
            for layer in layers_uniq:
                if self._layer_in_same_repo(repo, tag, layer):
                    logger.debug("Not deleting since we found another tag using digest: %s", layer)
                    continue
    
                self._delete_layer(repo, layer)
                if layer in all_links_not_in_current_repo:
                    logger.debug("Blob found in another repository. Not deleting: %s", layer)
                else:
                    self._delete_blob(layer)
    
            self._delete_revisions(repo, revisions_to_delete, blobs_to_keep)
            self._delete_dir(tag_dir)
    
        def delete_untagged(self, repo):
            """delete all untagged data from repo"""
            logger.debug("Deleting utagged data from repository '%s'", repo)
            repositories_dir = os.path.join(self.registry_data_dir, "repositories")
            repo_dir = os.path.join(repositories_dir, repo)
            if not os.path.isdir(repo_dir):
                raise RegistryCleanerError("No repository '{0}' found in repositories "
                                           "directory {1}/repositories".
                                           format(repo, self.registry_data_dir))
            tagged_links = set(get_links(repositories_dir, _filter="current"))
            layers_to_protect = []
            for link in tagged_links:
                layers_to_protect.extend(self._get_layers_from_blob(link))
    
            unique_layers_to_protect = set(layers_to_protect)
            for layer in unique_layers_to_protect:
                logger.debug("layer_to_protect: %s", layer)
    
            tagged_revisions = set(get_links(repo_dir, _filter="current"))
    
            revisions_to_delete = []
            layers_to_delete = []
    
            dir_for_revisions = os.path.join(repo_dir, "_manifests/revisions/sha256")
            for rev in os.listdir(dir_for_revisions):
                if rev not in tagged_revisions:
                    revisions_to_delete.append(os.path.join(dir_for_revisions, rev))
                    for layer in self._get_layers_from_blob(rev):
                        if layer not in unique_layers_to_protect:
                            layers_to_delete.append(layer)
    
            unique_layers_to_delete = set(layers_to_delete)
    
            self._delete_revisions(repo, revisions_to_delete)
            for layer in unique_layers_to_delete:
                self._delete_blob(layer)
                self._delete_layer(repo, layer)
    
    
        def get_tag_count(self, repo):
            logger.debug("Get tag count of repository '%s'", repo)
            repo_dir = os.path.join(self.registry_data_dir, "repositories", repo)
            tags_dir = os.path.join(repo_dir, "_manifests/tags")
    
            if os.path.isdir(tags_dir):
                tags = os.listdir(tags_dir)
                return len(tags)
            else:
                logger.info("Tags directory does not exist: '%s'", tags_dir)
                return -1
    
    def main():
        """cli entrypoint"""
        parser = argparse.ArgumentParser(description="Cleanup docker registry")
        parser.add_argument("-i", "--image",
                            dest="image",
                            required=True,
                            help="Docker image to cleanup")
        parser.add_argument("-v", "--verbose",
                            dest="verbose",
                            action="store_true",
                            help="verbose")
        parser.add_argument("-n", "--dry-run",
                            dest="dry_run",
                            action="store_true",
                            help="Dry run")
        parser.add_argument("-f", "--force",
                            dest="force",
                            action="store_true",
                            help="Force delete (deprecated)")
        parser.add_argument("-p", "--prune",
                            dest="prune",
                            action="store_true",
                            help="Prune")
        parser.add_argument("-u", "--untagged",
                            dest="untagged",
                            action="store_true",
                            help="Delete all untagged blobs for image")
        args = parser.parse_args()
    
    
        handler = logging.StreamHandler()
        handler.setFormatter(logging.Formatter(u'%(levelname)-8s [%(asctime)s]  %(message)s'))
        logger.addHandler(handler)
    
        if args.verbose:
            logger.setLevel(logging.DEBUG)
        else:
            logger.setLevel(logging.INFO)
    
    
        # make sure not to log before logging is setup. that'll hose your logging config.
        if args.force:
            logger.info(
                "You supplied the force switch, which is deprecated. It has no effect now, and the script defaults to doing what used to be only happen when force was true")
    
        splitted = args.image.split(":")
        if len(splitted) == 2:
            image = splitted[0]
            tag = splitted[1]
        else:
            image = args.image
            tag = None
    
        if 'REGISTRY_DATA_DIR' in os.environ:
            registry_data_dir = os.environ['REGISTRY_DATA_DIR']
        else:
            registry_data_dir = "/opt/registry_data/docker/registry/v2"
    
        try:
            cleaner = RegistryCleaner(registry_data_dir, dry_run=args.dry_run)
            if args.untagged:
                cleaner.delete_untagged(image)
            else:
                if tag:
                    tag_count = cleaner.get_tag_count(image)
                    if tag_count == 1:
                        cleaner.delete_entire_repository(image)
                    else:
                        cleaner.delete_repository_tag(image, tag)
                else:
                    cleaner.delete_entire_repository(image)
    
            if args.prune:
                cleaner.prune()
        except RegistryCleanerError as error:
            logger.fatal(error)
            sys.exit(1)
    
    
    if __name__ == "__main__":
        main()
    View Code

    # 首先,用export定义变量 REGISTRY_DATA_DIR 也就是Registry设置的映射盘路径

    # 然后,执行脚本 -i 跟上镜像完整名字

      

     

    使用harbor 搭建私有仓库

     PS: 注意安装的时候上面不能同时存在Registry!!!

    # 记得先修改不使用https

       

      

     # 安装docker 编排工具

    yum install docker-compose 

    # haror 离线包

    https://github.com/goharbor/harbor/releases

    解压,导入镜像.tar 

    拷贝模板

    cp harbor.yml.tmpl harbor.yml

    修改配置文件

    注释掉https(生产环境视情况)

    默认是80端口(生产环境注意修改)

    查看Harbor初始密码(生产环境注意修改)

    admin

    Harbor12345

    运行 准备prepare 脚本

    运行 安装 install.sh 脚本

      

    新建项目(tag分类),取名,选择“公开”

    【成员】创建用户密码方便用户push镜像过来

    # 直接推送,会发现提示需要验证(就是刚刚创建的用户)

    注:推送镜像的时候一定要注意命名规则,镜像名字要叫如下方式才可push

    <Harbor服务器IP或域名>/<harbor项目名>/<自定义的镜像名>:<TAG>,例如:

    118.xxx.xxx.2/cka/c7:loki_v1 
    118.xxx.xxx.2/cka/busybox:latest

    # 登录用户

     

    # 拉取

    docker pull 118.xxx.xxx.2/cka/busybox

     

    限制容器资源

    目的:防止各个容器资源抢占

    Cgroup : linux 系统下的功能

    /etc/systemd/system/memload.service.d

    # 使用memload 来进行测试

     memload <数值>

    方法一: 创建容器的时候参数限制

    OOM : 内存溢出  需求内存超过限制内存值

      

    # 用来长时间占用cpu  测试

      

    # 查看某个命令运行在哪些CPU上 

     --cpuset-cpus=0  #指定创建的容器在哪个cpu上运行

      

      

    # 针对CPU和内存设定值修改方法

    docker update  

    --cpuset-cpus <使用的CPU核心ID>   e.g.   docker update bbox_t1 --cpuset-cpus 10-15 ## 你要确定你有这么多核心的cpu才能设置这个值

    --memory-swap <这个值要大于内存值> ## 如果小于就会如下报错提示   e.g. docker update bbox_t1 --memory-swap 1024m

    # 内存限制小于内存的SWAP的限制值,请同步修改内存SWAP值。

     Memory limit should be smaller than already set memoryswap limit, update the memoryswap at the same time

    -m <内存大小>  e.g. docker update bbox_t1 -m 512m

      

    Block IO 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。

    block io 权重

    (1)参数说明

    • 默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block io 的优先级。 
    •  --blkio–weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。

    限制 bps 和 iops 

    (1)bps 和 iops介绍:
    • bps 是 byte per second,每秒读写的数据量。 
    • iops 是 io per second,每秒 IO 的次数。
     
    (2)可通过以下参数控制容器的 bps 和 iops:
    • --device-read-bps:限制读某个设备的 bps。
    • --device-write-bps:限制写某个设备的 bps。
    • --device-read-iops:限制读某个设备的 iops。
    • --device-write-iops:限制写某个设备的 iops。

    ctop 命令研究(仅能检测容器的资源情况)

    sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.5/ctop-0.7.5-linux-amd64 -O /usr/local/bin/ctop

    sudo chmod +x /usr/local/bin/ctop

    # 界面展示

    # 基本常用命令  e 进入shell模式,l 进入log模式,o查看容器ip和资源信息,q退出

    监控容器 

    docker stats  # 监控容器基本信息

    # 原理读取物理机这些目录

     cadvisor  # google 建立一个监控容器,查看其他容器资源消耗

    scope 工具: Weave是由Zett.io公司开发的,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。

    cadvisor:  为了解决docker stats的问题(存储、展示),谷歌开源的cadvisor诞生了,cadvisor不仅可以搜集一台机器上所有运行的容器信息,还提供基础查询界面和http接口,方便其他组件如Prometheus进行数据抓取

  • 相关阅读:
    强化学习的基本迭代方法
    基于文本描述的事务聚类
    学习强化学习之前需要掌握的3种技能
    其它 华硕 ASAU S4100U 系统安装 win10安装 重装系统 Invalid Partition Table 解决
    数据分析 一些基本的知识
    Python 取样式的内容 合并多个文件的样式 自定义样式
    电商 Python 生成补单公司需要的评论格式3
    SpringBlade 本地图片上传 生成缩略图
    SQL Server 字符串截取
    SpringBlade 本地图片上传
  • 原文地址:https://www.cnblogs.com/Cong0ks/p/14458321.html
Copyright © 2011-2022 走看看