K8S搭建docker本地镜像仓库
私有仓库最常用的有Registry、Harbor两种。Registry是docker官方的项目,Harbor是VMware公司开源的企业级Docker Registry项目。
一、Docker Harbor
1、Docker Harbor概述:
有可视化的Web管理界面,可以方便管理Docker镜像,又提供了多个项目的镜像权限管理及控制功能。
2、Harbor的优势:
1>. 基于角色控制
2>. 基于镜像的复制策略
3>. 支持LDAP/AD
4>. 图像删除和垃圾收集
5>. 图像UI
6>. 审计
7>. RESTful API
3、 Harbor知识点
1>. Proxy:通过一个前置的反向代理统一接收浏览器、Docker客户端的请求,并将请求转发给后端不同的服务
2>. Registry:负责存储Docker镜像,并处理docker push/pull命令
3>. Core services:Harbor的核心功能,包括UI、webhook、token服务
4>. Database:为core services提供数据库服务
5>. Log collector:负责收集其他组件的log,供日后进行分析
4、Docker私有仓库架构
如上图所示:
所有的请求都经过proxy代理,proxy代理转发给Core services和Registry,其中Core services包括UI界面、token令牌和webhook网页服务功能,Registry主要提供镜像存储功能。如果要进行下载上传镜像,要经过token令牌验证然后从Registry获取或上传镜像,每一次下载或上传都会生成日志记录,会记入Log collector,而用户身份权限及一些镜像语言信息会被存储在Database中。
5、Harbor构建Docker私有仓库
1>. 环境配置:
server:CentOS7.9 10.100.2.33 docker-v20.10.8、docker-compose-v1.29.2、harbor-offline-v2.3.2
client:CentOS7.9 10.100.2.34 docker-v20.10.8
2>. 部署Harbor服务
Harbor 被部署为多个 Docker 容器,因此可以部署在任何支持 Docker 的 Linux 发行版上。服务端主机需要安装 Python、Docker 和 Docker Compose。
1) 官方下载地址:
harbor:https://github.com/goharbor/harbor/releases/download/v2.3.2/harbor-offline-installer-v2.3.2.tgz
docker-compose:https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
2) 安装docker:
在线安装:
yum install yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 注:docker官方源:yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce
systemctl enable docker --now
离线安装:
在线下载RPM包:
yum install yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yumdownloader --resolve --destdir /root/docker_rpm docker-ce
或:yum install --downloadonly --downloaddir /root/docker_rpm docker-ce
上传RPM包到离线环境安装:
yum install /root/docker_rpm/*.rpm
systemctl enable docker --now
3) 安装docker-compose和准备harbor:
安装docker-compose:
cp docker-compose-Linux-x86_64 /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose
或使用yum安装:yum install docker-compose
安装harbor:
tar zxvf harbor-offline-installer-v2.3.2.tgz -C /usr/local/
cd /usr/local/harbor/
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
hostname: reg.k8stest.com
http:
port: 80
https:
port: 443
certificate: /usr/local/harbor/ssl/harbor.crt
private_key: /usr/local/harbor/ssl/harbor.key
data_volume: /usr/local/harbor/data
harbor_admin_password: Harbor12345
mkdir ssl data
4) 生成证书
可以使用其他CA服务器颁发证书,也可以使用本机生成自签名证书。
使用自签名证书
cd /etc/pki/CA/
touch index.txt && echo 01> serial
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=harbor-server" -days 3650 -out ca.crt
openssl genrsa -out harbor.key 2048
openssl req -new -key harbor.key -subj "/CN=harbor-server" -out harbor.csr
openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out harbor.crt -days 3650
拷贝证书到/usr/local/harbor/ssl目录
cp harbor.key harbor.crt /usr/local/harbor/ssl/
5) 安装harbor
cd /usr/local/harbor/
./install.sh
docker-compose ps
Habor 服务启停:
注意:如果harbor.yml配置修改了,要先执行"./prepare"命令进行配置载入,然后再重启harbor服务。
查看Habror:docker-compose ps
启动Harbor:docker-compose start
停止Harbor:docker-compose stop
重启Harbor:docker-compose restart
另外:Harbor还可以通过down和up命令去停止和启动,只不过这种方式是删除、创建的关停和启动。
docker-compose down -v
docker-compose up -d
注1:
执行此命令时必须cd到项目的根目录下("cd /usr/local/harbor/"),或者指定docker-compose.yml文件:
docker-compose -f /usr/local/harbor/docker-compose.yml ps
否则提示如下错误:
ERROR:
Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?
Supported filenames: docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml
注2:
在服务器重启时,harbor的服务会有启动失败的情况,提示:"Exited (137)"
通过 docker logs registry 看不到有用的日志信息。
通过 docker inspect registry 查看container状态:
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 137,
"Error": "failed to initialize logging driver: dial tcp [::1]:1514: connect: connection refused",
"StartedAt": "2021-09-25T07:13:09.167745719Z",
"FinishedAt": "2021-09-25T07:21:30.770117401Z",
"Health": {
"Status": "unhealthy",
"FailingStreak": 0,
...
}
可以看到Error错误提示,原因是:日志服务未先启动,而其它服务需要先到日志服务器注册,所以会造成端口访问拒绝。
解决办法:注册harbor服务,重启服务器harbor服务也能正常启动了。
注册harbor服务:
vim /usr/lib/systemd/system/harbor.service
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor
[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
允许开机自启动,查看harbor状态,所有服务状态正常。
systemctl enable harbor --now
systemctl status harbor
6) 访问Harbor
修改windows客户端的hosts文件:
10.100.2.33 reg.k8stest.com
打开浏览器,输入自定义域名:https://reg.k8stest.com 即可打开页面。
输入用户名:admin,密码登录(密码在harbor.yml中定义)。
可以创建项目、用户、仓库等。例如创建一个私有的testproj项目,用于上传镜像。
7) 配置服务端daemon.json文件
mkdir /etc/docker
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["reg.k8stest.com"],
"registry-mirrors":
[
"https://pee6w651.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://registry.docker-cn.com"
]
}
vim /etc/hosts
10.100.2.33 reg.k8stest.com
systemctl restart docker
8) 镜像管理
登录镜像仓库
docker login -u admin https://reg.k8stest.com
docker logout
docker login -u admin http://reg.k8stest.com
下载镜像(内网环境可以直接上传)
docker pull ubuntu
docker tag ubuntu:latest reg.k8stest.com/testproj/ubuntu:v1
docker images |grep k8stest
docker login http://reg.k8stest.com
docker push reg.k8stest.com/testproj/ubuntu
在控制台可以看到刚上传的镜像。
9) 客户端访问
客户端访问和本地访问差不多。
编辑docker的daemon.json文件:
该版本的harbor默认使用的https协议,如没有证书或为自签证书,则需使用"insecure-registries"字段,将harbor访问域名加入其中。
mkdir /etc/docker
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["reg.k8stest.com"],
"registry-mirrors": ["http://reg.k8stest.com"]
}
注:"insecure-registries"参数也可以放在docker启动文件上:
vim /usr/lib/systemd/system/docker.service
修改启动项:ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
为ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry reg.mytest.com --containerd=/run/containerd/containerd.sock
systemctl start docker
vim /etc/hosts
10.100.2.33 reg.k8stest.com
上传下载镜像
docker login http://reg.k8stest.com
docker pull reg.k8stest.com/testproj/ubuntu:v1
docker tag reg.k8stest.com/testproj/ubuntu:v1 reg.k8stest.com/testproj/ubuntu:v2
docker push reg.k8stest.com/testproj/ubuntu:v2
docker tag nginx:latest reg.k8stest.com/testproj/nginx:v2
docker push reg.k8stest.com/testproj/nginx:v2
在控制台查看操作日志:
二、Docker Registry
三、如何在K8S中使用私有镜像库
前言:
在企业落地 K8S 的过程中,私有镜像库 (专用镜像库) 必不可少,特别是在 Docker Hub 开始对免费用户限流之后, 越发的体现了搭建私有镜像库的重要性。
私有镜像库不但可以加速镜像的拉取还可以避免因特有的"网络问题"导致镜像拉取失败尴尬。
当然部署了私有镜像库之后也需要对镜像库设置一些安全策略,大部分私有镜像库采用 IP访问策略+认证 (非公开项目) 的方式对镜像库进行安全保护。
那么对于含有认证限制的镜像库,在 K8S 中该如何优雅的集成呢?
下文就总结了在 K8S 中使用私有镜像库的几种情况和方式。
1>. 在 K8S 中使用私有镜像库
首先要确定私有镜像库的授权使用方式,在针对不同的使用方式选择对应的认证配置。
1) 针对节点 (Node):
这个应该是企业使用 K8S 时最常用的方式,一般也只要使用这个就够了,并且该方案几乎是使用了私有镜像库之后必不可少的配置,它可以做到:
<1>. 在节点环境中进行一定的配置,不需要在 K8S 中进行其它的配置即可享有具体私有库的权限。
<2>. 该方案对该节点上的所有 Pods 生效,同时还对非 Pods 镜像生效,例如: kubelet 的 pause 镜像,这个非常关键。
2) 针对服务账号 (ServiceAccount)、针对命名空间 (Namespace):
配置了该 ServiceAccount 的 Pod 都享有这个 ServiceAccount 所配置的镜像库认证设置。
还可以利用 K8S 中 default ServiceAccount 机制,达到对一个具体命名空间中没有特殊设置的所有 Pod 生效。
3) 针对 Pod:
针对具体的 Pod 进行认证配置,该 Pod 就会具有私有库的权限。
Deployment、DaemonSet、StatefulSet、CronJob、Job 等资源都使用了PodTemplate 最终都会以具体的 Pod 资源体验,所以在 PodTemplate 中配置也算对 Pod 配置。
2>. 配置步骤
前提条件:
1. 一个可用私有镜像库 (可用采用 Harbor 搭建)
2. 私有镜像库的账号和密码 (推荐只给只读权限)
3. CRI 基于 Docker (其它的 CRI 暂没有验证)
1) 针对节点 (Node) 配置
1. 编写 Docker 配置文件
2. 将 Docker 配置文件放在指定位置
3. 重启 kubelet
<1>. 编写 Docker 配置文件
首先编写 Docker 的认证配置文件, 格式如下:
{
"auths": {
"<HOST>": {
"auth": "<BASIC_AUTHORIZATION>"
}
}
}
注:
<HOST> # 为私有镜像库的地址, 例如: hub.docker.com
<BASIC_AUTHORIZATION> # 为 BASE64(<USERNAME>:<PASSWORD>)
例如:
cmVhZGVyOjEyMzQ1Ng==,其中账号是:reader,密码是:123456
使用:拼接后进行 base64
完整的配置文件,例如:
{
"auths": {
"hub.docker.com": {
"auth": "cmVhZGVyOjEyMzQ1Ng=="
},
"harbor.domain.cn": {
"auth": "cmVhZGVyOiFAIzQ1Ng=="
}
}
}
如有多个镜像库在 auths 节中进行添加即可。
<2>. 将 Docker 配置文件放在指定位置
推荐放在 kubelet 根目录中,配置文件需以 config.json 命名。
默认的 kubelet 根目录一般为 /var/lib/kubelet (如有修改进行替换即可),也就是需要放置在 /var/lib/kubelet/config.json。
还可以放在以下位置:
{--root-dir:-/var/lib/kubelet}/config.json
{cwd of kubelet}/config.json
${HOME}/.docker/config.json
/.docker/config.json
{--root-dir:-/var/lib/kubelet}/.dockercfg
{cwd of kubelet}/.dockercfg
${HOME}/.dockercfg
/.dockercfg
参考文档:
https://kubernetes.io/zh/docs/concepts/containers/images/
https://kubernetes.io/docs/concepts/containers/images/#configuring-nodes-to-authenticate-to-a-private-registry
注意:
放在 ${HOME} 开头的位置,需要在 kubelet service 环境中配置 HOME 的路径,不然不会生效。例如:HOME=/root
下面是使用 kubeadm 安装的环境中可用的脚本,如果不是请自行配置。
echo "HOME=${HOME}" >> /var/lib/kubelet/kubeadm-flags.env
<3>. 重启 kubelet
如果 init 不是 systemd,请自行替换服务重启的命令
systemctl daemon-reload; systemctl restart kubelet
2) 针对服务账号 (ServiceAccount)、针对命名空间 (Namespace)
1. 创建一个 Docker Registry Secret资源
2. 设置 ServiceAccount 的 imagePullSecrets
3. 将 Pod 的 serviceAccountName 设置为该 ServiceAccount 的名称
<1>. 创建一个 Docker Registry Secret资源
使用 kubectl cli 创建Registry Secret资源:
kubectl create secret docker-registry <SECRET_NAME> --docker-server=<DOCKER_REGISTRY_SERVER> --docker-username=<DOCKER_USER> --docker-password=<DOCKER_PASSWORD> -n <NAMESPACE>
其中:
<SECRET_NAME> # 是Secret资源的名称, 在编辑 SA 资源的时需要引用
<DOCKER_REGISTRY_SERVER> # 是私有镜像库的服务器地址
<DOCKER_USER> # 是私有镜像库认证的账号
<DOCKER_PASSWORD> # 是私有镜像库认证的密码
<NAMESPACE> # 是命名空间名称
示例命令如下:
kubectl create secret docker-registry docker-reader-secret --docker-server=harbor.domain.cn --docker-username=reader --docker-password=123456 -n basic
使用 yaml 创建Registry Secret资源:
cat docker-reader-secret.yaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfUkVHSVNUUllfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImF1dGgiOiJSRTlEUzBWU1gxVlRSVkk2UkU5RFMwVlNYMUJCVTFOWFQxSkUifX19
kind: Secret
metadata:
name: docker-reader-secret
namespace: default
type: kubernetes.io/dockerconfigjson
其中:
.dockerconfigjson 是base64之后的字符串,具体内容参考 "编写 Docker 配置文件" 节中的内容。
https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
kubectl apply -f docker-reader-secret.yaml
<2>. 设置 ServiceAccount 的 imagePullSecrets
apiVersion: v1
kind: ServiceAccount
metadata:
name: service1
namespace: basic
secrets:
- name: service1-token-mp4qs
imagePullSecrets:
- name: docker-reader-secret
<3>. 将资源的 serviceAccountName 设置为该 ServiceAccount 的名称
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
serviceAccountName: service1
<4>. 如何针对命名空间内的所有Pod?
K8S 中有个默认的机制,会在命名空间中创建一个名称为 default 的 ServiceAccount (sa) 资源。
并且在资源没有单独指定 serviceAccountName 时, 默认使用 default 作为serviceAccountName。
所以我们只需设置 default ServiceAccount 的 imagePullSecrets 即可对该命名空间中没有特殊指定 serviceAccountName 字段的 Pod 生效了。
3) 针对 Pod
1. 创建一个 Docker Registry Secret资源
2. 设置 Pod 的 imagePullSecrets
<1>. 创建一个 Docker Registry Secret资源
参考 "创建一个 Docker Registry Secret资源" 节中的内容
<2>. 设置 Pod 的 imagePullSecrets
一个具体的 Pod
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: docker-reader-secret
针对具有 PodTemplate 内容的资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullSecrets:
- name: docker-reader-secret
最后更新于 2021-09-25 19:12:51 并被添加「k8s」标签,已有 2965 位童鞋阅读过。
本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处