部署 harbor 私有仓库
安装下载依赖包
安装docker-compose
从 docker compose 发布页面下载最新的 docker-compose 二进制文件,本文以1.25.4为例
cd /opt/k8s/work/harbor/ wget https://github.com/docker/compose/releases/download/1.25.4/docker-compose-Linux-x86_64 mv docker-compose-Linux-x86_64 /opt/k8s/bin/docker-compose
chmod a+x /opt/k8s/bin/docker-compose
export PATH=/opt/k8s/bin:$PATH下载harbor二进制文件
从 harbor 发布页面下载最新的 harbor 离线安装包,本文以v1.9.4为例
cd /opt/k8s/work/harbor/ wget https://github.com/goharbor/harbor/releases/download/v1.9.4/harbor-offline-installer-v1.9.4.tgz tar -xzvf harbor-offline-installer-v1.5.1.tgz
导入 docker images
导入离线安装包中 harbor 相关的 docker imagescd /opt/k8s/work/harbor/harbor
docker load -i harbor.v1.9.4.tar.gz
以http形式启动
修改harbor.yml文件
修改 hostname、data_volume属性值cd /opt/k8s/work/harbor/harbor cp harbor.yml harbor.yml.bak vim harbor.yml
修改信息如下
diff harbor.yml harbor.yml.bak
5c5
< hostname: 192.168.0.107
---
> hostname: reg.mydomain.com
40c40
< data_volume: /data/k8s/harbor/data
---
> data_volume: /data加载和启动 harbor 镜像
cd /opt/k8s/work/harbor/harbor
mkdir -p /data/k8s/harbor/data
chmod 777 /var/run/docker.sock /data/k8s/harbor/data
./install.sh启动日志
Note: docker version: 18.09.6 Note: docker-compose version: 1.25.4
# Configuration file of Harbor [Step 1]: loading Harbor images ...
Loaded image: goharbor/harbor-core:v1.9.4
Loaded image: goharbor/clair-photon:v2.1.0-v1.9.4
Loaded image: goharbor/harbor-portal:v1.9.4
Loaded image: goharbor/nginx-photon:v1.9.4
Loaded image: goharbor/chartmuseum-photon:v0.9.0-v1.9.4
Loaded image: goharbor/prepare:v1.9.4
Loaded image: goharbor/redis-photon:v1.9.4
Loaded image: goharbor/registry-photon:v2.7.1-patch-2819-2553-v1.9.4
Loaded image: goharbor/notary-server-photon:v0.6.1-v1.9.4
Loaded image: goharbor/harbor-log:v1.9.4
Loaded image: goharbor/harbor-db:v1.9.4
Loaded image: goharbor/harbor-jobservice:v1.9.4
Loaded image: goharbor/harbor-registryctl:v1.9.4
Loaded image: goharbor/notary-signer-photon:v0.6.1-v1.9.4
Loaded image: goharbor/harbor-migrator:v1.9.4 [Step 2]: preparing environment ...
prepare base dir is set to /opt/k8s/work/harbor/harbor
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
Generated and saved secret to file: /secret/keys/secretkey
Generated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crt
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir [Step 3]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-db ... done
Creating redis ... done
Creating harbor-portal ... done
Creating registry ... done
Creating registryctl ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating nginx ... done ✔ ----Harbor has been installed and started successfully.---- Now you should be able to visit the admin portal at http://192.168.0.107.
For more details, please visit https://github.com/goharbor/harbor .查看启动状态
root@master:/opt/k8s/work/harbor/harbor# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------
harbor-core /harbor/harbor_core Up (healthy)
harbor-db /docker-entrypoint.sh Up (healthy) 5432/tcp
harbor-jobservice /harbor/harbor_jobservice ... Up (healthy)
harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal nginx -g daemon off; Up (healthy) 8080/tcp
nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp
redis redis-server /etc/redis.conf Up (healthy) 6379/tcp
registry /entrypoint.sh /etc/regist ... Up (healthy) 5000/tcp
registryctl /harbor/start.sh Up (healthy)如果有不是healthy状态的对象,到/var/log/harbor/目录下查看对应对象的日志
harbor官方提供的启动文件中容器的日志类型是syslog,不支持用docker logs查看
ls /var/log/harbor/
core.log jobservice.log portal.log postgresql.log proxy.log redis.log registryctl.log registry.log
```
浏览器访问 http://192.168.0.107,用账号 admin 和 harbor.yml 配置文件中的默认密码 Harbor12345 登陆系统。

创建一个新的项目
docker命令拉取和上传镜像
执行login
root@slave:~# docker login -u admin -p Harbor12345 192.168.0.107
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://192.168.0.107/v2/: dial tcp 192.168.0.107:443: connect: connection refused因为docker命令默认采用https和API交互,而我们的harbor是http的,所以不能执行,需要在/etc/docker/daemon.json中追加insecure-registries配置
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com"],
"insecure-registries": ["192.168.0.107"],
"max-concurrent-downloads": 20,
"live-restore": true,
"max-concurrent-uploads": 10,
"data-root": "/data/k8s/docker/data",
"log-opts": {
"max-size": "100m",
"max-file": "5"
}
}重新启动docker服务
root@slave:~# systemctl restart docker root@slave:~# docker login -u admin -p Harbor12345 192.168.0.107
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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向harbor中刚创建的私有项目里面上传镜像
root@slave:~# docker tag k8s.gcr.io/pause:3.1 192.168.0.107/k8s/pause:3.1
root@slave:~# docker push 192.168.0.107/k8s/pause:3.1
The push refers to repository [192.168.0.107/k8s/pause]
e17133b79956: Pushed
3.1: digest: sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d size: 527浏览器查看
从harbor中下载镜像
root@slave:~# docker rmi 192.168.0.107/k8s/pause:3.1
Untagged: 192.168.0.107/k8s/pause:3.1
Untagged: 192.168.0.107/k8s/pause@sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d
root@slave:~# docker pull 192.168.0.107/k8s/pause:3.1
3.1: Pulling from k8s/pause
Digest: sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d
Status: Downloaded newer image for 192.168.0.107/k8s/pause:3.1
以https形式启动
下列操作的工作目录/opt/k8s/work/harbor/harbor是解压harbor离线安装文件后 生成的 harbor 目录
停止harbor(如果没有启动过,则跳过该步骤)
cd /opt/k8s/work/harbor/harbor root@master:/opt/k8s/work/harbor/harbor# COMPOSE_HTTP_TIMEOUT=200 docker-compose down -v
Stopping nginx ... done
Stopping harbor-jobservice ... done
Stopping harbor-core ... done
Stopping registryctl ... done
Stopping redis ... done
Stopping harbor-portal ... done
Stopping harbor-db ... done
Stopping registry ... done
Stopping harbor-log ... done
Removing harbor-log ... done
Removing network harbor_harbor执行docker-compose down -v后,有可能对应的容器还在,可以执行强制停掉容器
docker ps | grep harbor | awk '{print $1}' | xargs -I {} docker rm -f {}
创建 harbor nginx 服务器使用的 x509 证书,本文档采用cfssl工具生成,也可以利用openssl生成,具体步骤参考harbor-openssl
创建harbor用的CA根证书
创建配置文件
cd /opt/k8s/work/harbor/
cat > harbor-ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"harbor": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF创建证书签名请求文件
cd /opt/k8s/work/harbor/ cat > harbor-ca-csr.json <<EOF
{
"CN": "harbor-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "NanJing",
"L": "NanJing",
"O": "k8s",
"OU": "system"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF生成自签名的根证书,分发证书
cd /opt/k8s/work/harbor/ cfssl gencert -initca harbor-ca-csr.json | cfssljson -bare harbor-ca ls harbor-ca*pem mkdir -p /etc/harbor/cert mv harbor-ca*pem harbor-ca-config.json /etc/harbor/cert
创建harbor用的证书
生成证书请求文件
cd /opt/k8s/work/harbor/ cat > harbor-server-csr.json <<EOF
{
"CN": "harbor",
"hosts": [
"127.0.0.1",
"192.168.0.107"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "NanJing",
"L": "NanJing",
"O": "k8s",
"OU": "system"
}
]
}
EOF- hosts 字段指定授权使用该证书的当前部署节点 IP
生成证书
cfssl gencert -ca=/etc/harbor/cert/harbor-ca.pem \
-ca-key=/etc/harbor/cert/harbor-ca-key.pem
-config=/etc/harbor/cert/harbor-ca-config.json
-profile=harbor harbor-server-csr.json | cfssljson -bare harbor-server
ls harbor-server*pem
mv harbor-server*pem /etc/harbor/cert
```
编辑配置文件
修改 hostname、data_volume属性值,去除默认的http方式,追加https的配置
cd /opt/k8s/work/harbor/harbor vim harbor.yml
修改内容如下
diff harbor.yml harbor.yml.bak
5c5
< hostname: 192.168.0.107
---
> hostname: reg.mydomain.com
8c8
< #http:
---
> http:
10c10
< # port: 80
---
> port: 80
13c13
< https:
---
> # https:
15c15
< port: 443
---
> # port: 443
17,18c17,18
< certificate: /etc/harbor/cert/harbor-server.pem
< private_key: /etc/harbor/cert/harbor-server-key.pem
---
> # certificate: /your/certificate/path
> # private_key: /your/private/key/path
40c40
< data_volume: /data/k8s/harbor/data
---
> data_volume: /data生成配置文件(如果没有启动过,则跳过该步骤)
cd /opt/k8s/work/harbor/harbor ./prepare
执行日志
prepare base dir is set to /opt/k8s/work/harbor/harbor
Clearing the configuration file: /config/log/rsyslog_docker.conf
Clearing the configuration file: /config/log/logrotate.conf
Clearing the configuration file: /config/jobservice/config.yml
Clearing the configuration file: /config/jobservice/env
Clearing the configuration file: /config/db/env
Clearing the configuration file: /config/registryctl/config.yml
Clearing the configuration file: /config/registryctl/env
Clearing the configuration file: /config/nginx/nginx.conf
Clearing the configuration file: /config/registry/config.yml
Clearing the configuration file: /config/registry/root.crt
Clearing the configuration file: /config/core/app.conf
Clearing the configuration file: /config/core/env
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
loaded secret from file: /secret/keys/secretkey
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir修改生成文件的访问权限
cd /opt/k8s/work/harbor/harbor
chmod -R 777 common启动harbor
如果是首次启动 执行
cd /opt/k8s/work/harbor/harbor mkdir -p /data/k8s/harbor/data
chmod 777 /var/run/docker.sock /data/k8s/harbor/data
./install.sh否则执行
docker-compose up -d
查看启动状态
root@master:/opt/k8s/work/harbor/harbor# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------------
harbor-core /harbor/harbor_core Up (healthy)
harbor-db /docker-entrypoint.sh Up (healthy) 5432/tcp
harbor-jobservice /harbor/harbor_jobservice ... Up (healthy)
harbor-log /bin/sh -c /usr/local/bin/ ... Up (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal nginx -g daemon off; Up (healthy) 8080/tcp
nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp
redis redis-server /etc/redis.conf Up (healthy) 6379/tcp
registry /entrypoint.sh /etc/regist ... Up (healthy) 5000/tcp
registryctl /harbor/start.sh Up (healthy)- nginx 暴露了两个端口http的80和https的443,使用http访问80会自动重定向到https
浏览器访问 https://192.168.0.107,用账号 admin 和 harbor.yml 配置文件中的默认密码 Harbor12345 登陆系统。
- 其中的k8s是在http模式下创建的项目,直接启动https的可参照上面创建
docker命令拉取和上传镜像
如果之前已经执行过docker login,配置修改后需要重新docker login,需要删除 /root/.docker/config.json文件
如果在/etc/docker/daemon.json中配置过insecure-registries,需要去掉,并重新启动docker服务
执行login
root@slave:~# docker login -u admin -p Harbor12345 192.168.0.107
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://192.168.0.107/v2/: x509: certificate signed by unknown authority
```
错误是说我们用的证书是自签名的证书,签发证书机构未经认证
解决方法是将签署 harbor-server 证书的 CA 证书拷贝到 /etc/docker/certs.d/192.168.0.107 目录下(需要在所有要访问harbor的节点上都执行此操作)
```
root@slave:~# mkdir -p /etc/docker/certs.d/192.168.0.107
root@slave:~# scp root@192.168.0.107:/etc/harbor/cert/harbor-ca.pem /etc/docker/certs.d/192.168.0.107/ca.crt
root@192.168.0.107's password:
harbor-ca.pem 100% 1306 283.7KB/s 00:00
root@slave:~# ls /etc/docker/certs.d/192.168.0.107/
ca.crt
```
重新执行login
```
root@slave:~# docker login -u admin -p Harbor12345 192.168.0.107
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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@slave:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kubernetesui/metrics-scraper v1.0.3 3327f0dbcb4a 2 weeks ago 40.1MB
busybox latest 6d5fcfe5ff17 7 weeks ago 1.22MB
coredns/coredns 1.6.6 cc4d8e8c6169 2 months ago 40.8MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 2 years ago 742kB
192.168.0.107/k8s/pause 3.1 da86e6ba6ca1 2 years ago 742kB
kubeimage/pause 3.1 da86e6ba6ca1 2 years ago 742kB
nginx 1.9.1 94ec7e53edfc 4 years ago 133MB
root@slave:~# docker tag busybox:latest 192.168.0.107/k8s/busybox:latest
root@slave:~# docker push 192.168.0.107/k8s/busybox:latest
The push refers to repository [192.168.0.107/k8s/busybox]
195be5f8be1d: Pushed
latest: digest: sha256:edafc0a0fb057813850d1ba44014914ca02d671ae247107ca70c94db686e7de6 size: 527
通过浏览器查看刚上传的镜像
从harbor下载镜像
root@slave:~# docker rmi 192.168.0.107/k8s/busybox:latest
Untagged: 192.168.0.107/k8s/busybox:latest
Untagged: 192.168.0.107/k8s/busybox@sha256:edafc0a0fb057813850d1ba44014914ca02d671ae247107ca70c94db686e7de6
root@slave:~# docker pull 192.168.0.107/k8s/busybox:latest
latest: Pulling from k8s/busybox
Digest: sha256:edafc0a0fb057813850d1ba44014914ca02d671ae247107ca70c94db686e7de6
Status: Downloaded newer image for 192.168.0.107/k8s/busybox:latest
kubernetes集群中使用私有的harbor镜像仓库
kubelet配置
kubernetes以pod为管理单元,而不是docker容器,在创建pod时,会先启动一个名为k8s.gcr.io/pause:3.1的镜像。
该镜像存在于google的镜像仓库中,国内不能直接访问,需要翻墙下载,如果集群新加节点,或者节点上这个镜像被清理掉,将导致pod不能启动
一般做法是搭建私有镜像仓库,把这个镜像push到我们的私有镜像仓库,再配置kubelet使用我们私有仓库中的pause镜像
具体做法是修改kubelet服务的启动文件:/etc/systemd/system/kubelet.service,在其中追加--pod-infra-container-image属性,属性值指向自己私有仓库中的pause镜像
例如
--pod-infra-container-image=192.168.0.107/k8s/pause:3.1
重启kubelet服务
systemctl restart kubelet
kubernetes和harbor进行认证
kubernetes提供了各种方式来访问各种镜像仓库,具体参考Using a Private Registry,本文采用配置节点的方式来使用私有仓库
在集群的任意一个节点上登陆harbor
root@slave:~# docker login -u admin -p Harbor12345 192.168.0.107
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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/config.json
root@slave:~# ls /root/.docker/
config.json
root@slave:~# cat /root/.docker/config.json
{
"auths": {
"192.168.0.107": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.09.6 (linux)"
}
}配置kubelet使用此认证文件
默认情况下,kubelet会从如下路径中查找私有仓库的认证文件
- {--root-dir:-/var/lib/kubelet}/config.json
- {cwd of kubelet}/config.json
- ${HOME}/.docker/config.json #须在环境变量文件中为 kubelet 显式设置 HOME=/root
- /.docker/config.json
此处我们将私有仓库的认证文件copy到kubelet的root目录下,此目录在kubelet.service中进行设置
例如--root-dir=/data/k8s/k8s/kubelet
copy私有仓库的认证文件到kubelet的root目录(所有运行kubelet,需要访问harbor的节点都需要),本环境中有两个节点
cp /root/.docker/config.json /data/k8s/k8s/kubelet/config.json scp /root/.docker/config.json root@192.168.0.114:/data/k8s/k8s/kubelet/config.json
验证
创建一个pod,image 指定私有仓库里面的镜像
cd /opt/k8s/yml cat > private-busybox.yml << EOF
apiVersion: v1
kind: Pod
metadata:
name: private-busybox
spec:
containers:
- name: private-busybox
image: 192.168.0.107/k8s/busybox:latest
command:
- sleep
- "3600"
EOF创建pod
root@master:/opt/k8s/yml# kubectl create -f private-busybox.yml
查看运行状态
root@master:/opt/k8s/yml# kubectl get pod | grep private-busybox
private-busybox 1/1 Running 0 108s通过docker命令,查看启动pod对应的容器的镜像名称
root@master:/opt/k8s/yml# docker ps | grep -e IMAGE -e private-busybox
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c2b43d9d9b3e 192.168.0.107/k8s/busybox "sleep 3600" About a minute ago Up About a minute k8s_private-busybox_private-busybox_default_98a4d4bd-fd46-4d9d-8ef9-95845ce7e53d_0
a4a84461d5fe 192.168.0.107/k8s/pause:3.1 "/pause" About a minute ago Up About a minute k8s_POD_private-busybox_default_98a4d4bd-fd46-4d9d-8ef9-95845ce7e53d_0 1/1 Running 0 5s可以看到启动的容器对应的镜像都是我们自己的私有仓库中的镜像
部署 harbor 私有仓库的更多相关文章
- 部署Harbor私有镜像仓库
Harbor私有镜像仓库无坑搭建 目录 1. harbor介绍 2. docker-ce的安装 3. docker-compose的安装 4. Harbor私有仓库的安装 5. 客户端连接镜像仓库配置 ...
- Docker Harbor私有仓库部署与管理 (超详细配图)
Docker Harbor私有仓库部署与管理 1.Harbor 介绍 2.Harbor部署 3.Harbor管理 1.Harbor 介绍: 什么是 Harbor ? Harbor 是 VMware 公 ...
- 搭建harbor私有仓库
2-1.项目说明 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由VMware开源,其通过添加一些企业必需的功能特性,例如安全.标识和管理等,扩展了开源 Docke ...
- Harbor私有仓库中如何彻底删除镜像释放存储空间?
简介: Harbor私有仓库运行一段时间后,仓库中存有大量镜像,会占用太多的存储空间.直接通过Harbor界面删除相关镜像,并不会自动删除存储中的文件和镜像.需要停止Harbor服务,执行垃圾回收命令 ...
- 部署docker-registry私有仓库
部署docker-registry私有仓库 创建文件夹 sudo mkdir -p /var/docker-data/{registry,certs,auth} sudo openssl req ...
- Docker以http访问Harbor私有仓库(一)
1 说明 前文Centos7搭建Harbor私有仓库(一)我们成功搭建Harbor,本篇我们主要配置Docker以http方式访问私有仓库 2 Docker配置 2.1 Mac系统 2.1.1 配置D ...
- Docker以https访问Harbor私有仓库(二)
1 说明 前文Centos7搭建Harbor私有仓库(二)中,我们以https方式搭建了Harbor,本篇我们主要配置Docker以https方式访问Harbor私有仓库 2 Docker配置 2.1 ...
- Centos7搭建Harbor私有仓库(二)
1 说明 前文Centos7搭建Harbor私有仓库(一)中成功搭建了Harbor,但,是以http方式搭建的,这里我们修改为https方式 以下基于镜像CentOS-7-x86_64-Minimal ...
- 在jenkins中使用shell命令推送当前主机上的docker镜像到远程的Harbor私有仓库
1.jenkins主机上的docker配置 先在Jenkins主机的docke上配置上Harbor私有仓库地址 cat /etc/docker/daemon.json { "insecure ...
随机推荐
- java基础之----非空判断
大家好,第一次写博客,一直想写博客,用于自我总结,也用于帮助新同学成长. 平常我们开发的时候,用到很多非空判断,但是很多同学用到的地方不是很准确,这里,我把自己平时遇到的坑跟大家说说.我废话不多,只想 ...
- 微服务统计,分析,图表,监控一体化的HttpReports项目在.Net Core 中的使用
简单介绍 HttpReports 是 .Net Core 下的一个Web项目, 适用于WebAPI,Ocelot网关应用,MVC项目,非常适合针对微服务应用使用,通过中间件的形式集成到您的项目中,可以 ...
- FlashFXP 5.0.0官方中文破解版,附文件下载地址和破解码
FlashFXP 5.0.0官方中文破解版是一个功能强大的 FXP/FTP 软件,融合了一些其他优秀 FTP 软件的优点,如像 CuteFTP 一样可以比较文件夹,支持彩色文字显示:像 BpFTP 支 ...
- 深入理解 CSS(Cascading Style Sheets)中的层叠(Cascading)
标题中的 Cascading 亦可以理解为级联. 进入正文,这是一个很有意思的现象.可以直接跳到 总结一下 部分,看完再回过头来阅读本文. 引子 假设我们有如下结构: <p class=&quo ...
- vPlayer 模块Demo
本文出自APICloud官方论坛 vPlayer iOS封装了AVPlayer视频播放功能(支持音频播放).iOS 平台上支持的视频文件格式有:WMV,AVI,MKV,RMVB,RM,XVID,MP4 ...
- html5中的Web Storage
html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage.sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有 ...
- JS绘图
https://www.highcharts.com.cn/demo/highcharts/ 百度的Echarts https://www.echartsjs.com/zh/index.html
- ii
char a[10], b[10], c[10], d[10],e[10],f[10],g[10],h[10]; scanf("%s %s %s %s", a, b, c, d); ...
- Data for the People: How to Make Our Post-Privacy Economy Work for You
等翻译成 chinese在看吧
- 「雅礼集训 2017 Day2」棋盘游戏
祝各位圣诞后快乐(逃) 题目传送门 分析: 首先棋盘上的路径构成的图是一张二分图 那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后 ...