详解 K8S 高可用部署,超详细!之 k8s 镜像仓库 harbor 环境部署
k8s 镜像仓库 harbor 环境部署
GitHub 地址:https://github.com/helm/helm/releases
这使用 helm 安装,所以得先安装 helm
1)安装 helm
mkdir -p /opt/k8s/helm && cd /opt/k8s/helm
wget https://get.helm.sh/helm-v3.9.0-rc.1-linux-amd64.tar.gz
tar -xf helm-v3.9.0-rc.1-linux-amd64.tar.gz
ln -s /opt/k8s/helm/linux-amd64/helm /usr/bin/helm
helm version
helm help
2)配置 hosts
192.168.0.120 myharbor.com
3)创建 stl 证书
mkdir /opt/k8s/helm/stl && cd /opt/k8s/helm/stl
# 生成 CA 证书私钥
openssl genrsa -out ca.key 4096
# 生成 CA 证书
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Guangdong/L=Shenzhen/O=harbor/OU=harbor/CN=myharbor.com" \
-key ca.key \
-out ca.crt
# 创建域名证书,生成私钥
openssl genrsa -out myharbor.com.key 4096
# 生成证书签名请求 CSR
openssl req -sha512 -new \
-subj "/C=CN/ST=Guangdong/L=Shenzhen/O=harbor/OU=harbor/CN=myharbor.com" \
-key myharbor.com.key \
-out myharbor.com.csr
# 生成 x509 v3 扩展
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=myharbor.com
DNS.2=*.myharbor.com
DNS.3=hostname
EOF
#创建 Harbor 访问证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in myharbor.com.csr \
-out myharbor.com.crt
4)安装 ingress
ingress 官方网站:https://kubernetes.github.io/ingress-nginx/
ingress 仓库地址:https://github.com/kubernetes/ingress-nginx
部署文档:https://kubernetes.github.io/ingress-nginx/deploy/
1、通过 helm 部署
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
2、通过 YAML 文件安装(本章使用这个方式安装 ingress)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml
如果下载镜像失败,可以用以下方式修改镜像地址再安装
牛逼啊!接私活必备的 N 个开源项目!赶快收藏
# 可以先把镜像下载,再安装
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.2.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml
# 修改镜像地址
sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.2.0\(.*\)@registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.2.0@' deploy.yaml
sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1\(.*\)$@registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1@' deploy.yaml
###还需要修改两地方
#1、kind: 类型修改成DaemonSet,replicas: 注销掉,因为DaemonSet模式会每个节点运行一个pod
#2、在添加一条:hostnetwork:true
#3、把LoadBalancer修改成NodePort
#4、在--validating-webhook-key下面添加- --watch-ingress-without-class=true
#5、设置master节点可调度
kubectl taint nodes k8s-master-168-0-113 node-role.kubernetes.io/control-plane:NoSchedule-
kubectl taint nodes k8s-master2-168-0-116 node-role.kubernetes.io/control-plane:NoSchedule-
kubectl apply -f deploy.yaml
5)安装 nfs
1、所有节点安装 nfs
yum -y install nfs-utils rpcbind
2、在 master 节点创建共享目录并授权
mkdir /opt/nfsdata
# 授权共享目录
chmod 666 /opt/nfsdata
3、配置 exports 文件
cat > /etc/exports<<EOF
/opt/nfsdata *(rw,no_root_squash,no_all_squash,sync)
EOF
# 配置生效
exportfs -r
exportfs 命令
常用选项
-a 全部挂载或者全部卸载
-r 重新挂载
-u 卸载某一个目录
-v 显示共享目录 以下操作在服务端上
4、启动 rpc 和 nfs(客户端只需要启动 rpc 服务)(注意顺序)
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server
查看
showmount -e
# VIP
showmount -e 192.168.0.120
-e 显示 NFS 服务器的共享列表
-a 显示本机挂载的文件资源的情况 NFS 资源的情况
-v 显示版本号
5、客户端
# 安装
yum -y install nfs-utils rpcbind
# 启动rpc服务
systemctl start rpcbind
systemctl enable rpcbind
# 创建挂载目录
mkdir /mnt/nfsdata
# 挂载
echo "192.168.0.120:/opt/nfsdata /mnt/nfsdata nfs defaults 0 1">> /etc/fstab
mount -a
6、rsync 数据同步
【1】rsync 安装
# 两端都得安装
yum -y install rsync
【2】配置
在/etc/rsyncd.conf 中添加
cat >/etc/rsyncd.conf<<EOF
uid = root
gid = root
#禁锢在源目录
use chroot = yes
#监听地址
address = 192.168.0.113
#监听地址tcp/udp 873,可通过cat /etc/services | grep rsync查看
port 873
#日志文件位置
log file = /var/log/rsyncd.log
#存放进程 ID 的文件位置
pid file = /var/run/rsyncd.pid
#允许访问的客户机地址
hosts allow = 192.168.0.0/16
#共享模块名称
[nfsdata]
#源目录的实际路径
path = /opt/nfsdata
comment = Document Root of www.kgc.com
#指定客户端是否可以上传文件,默认对所有模块为 true
read only = yes
#同步时不再压缩的文件类型
dont compress = *.gz *.bz2 *.tgz *.zip *.rar *.z
#授权账户,多个账号以空格分隔,不加则为匿名,不依赖系统账号
auth users = backuper
#存放账户信息的数据文件
secrets file = /etc/rsyncd_users.db
EOF
配置 rsyncd_users.db
cat >/etc/rsyncd_users.db<<EOF
backuper:123456
EOF
#官方要求,最好只是赋权600!
chmod 600 /etc/rsyncd_users.db
【3】rsyncd.conf 常用参数详解
rsyncd.conf 参数
rsyncd.conf 参数 参数说明 uid=root rsync 使用的用户。 gid=root rsync 使用的用户组(用户所在的组) use chroot=no 如果为 true,daemon 会在客户端传输文件前“chroot to the path”。这是一种安全配置,因为我们大多数都在内网,所以不配也没关系 max connections=200 设置最大连接数,默认 0,意思无限制,负值为关闭这个模块 timeout=400 默认为 0,表示 no timeout,建议 300-600(5-10 分钟) pid file rsync daemon 启动后将其进程 pid 写入此文件。如果这个文件存在,rsync 不会覆盖该文件,而是会终止 lock file 指定 lock 文件用来支持“max connections”参数,使得总连接数不会超过限制 log file 不设或者设置错误,rsync 会使用 rsyslog 输出相关日志信息 ignore errors 忽略 I/O 错误 read only=false 指定客户端是否可以上传文件,默认对所有模块为 true list=false 是否允许客户端可以查看可用模块列表,默认为可以 hosts allow 指定可以联系的客户端主机名或和 ip 地址或地址段,默认情况没有此参数,即都可以连接 hosts deny 指定不可以联系的客户端主机名或 ip 地址或地址段,默认情况没有此参数,即都可以连接 auth users 指定以空格或逗号分隔的用户可以使用哪些模块,用户不需要在本地系统中存在。默认为所有用户无密码访问 secrets file 指定用户名和密码存放的文件,格式;用户名;密码,密码不超过 8 位 [backup] 这里就是模块名称,需用中括号扩起来,起名称没有特殊要求,但最好是有意义的名称,便于以后维护 path 这个模块中,daemon 使用的文件系统或目录,目录的权限要注意和配置文件中的权限一致,否则会遇到读写的问题
【4】rsync 常用命令参数详解
rsync --help
rsync [选项] 原始位置 目标位置
常用选项 说明
-r 递归模式,包含目录及子目录中的所有文件
-l 对于符号链接文件仍然复制为符号链接文件
-v 显示同步过程的详细信息
-z 在传输文件时进行压缩goD
-p 保留文件的权限标记
-a 归档模式,递归并保留对象属性,等同于-rlpt
-t 保留文件的时间标记
-g 保留文件的属组标记(仅超级用户使用)
-o 保留文件的属主标记(仅超级用户使用)
-H 保留硬链接文件
-A 保留ACL属性信息
-D 保留设备文件及其他特殊文件
--delete 删除目标位置有而原始位置没有的文件
--checksum 根据对象的校验和来决定是否跳过文件
【5】启动服务(数据源机器)
#rsync监听端口:873
#rsync运行模式:C/S
rsync --daemon --config=/etc/rsyncd.conf
netstat -tnlp|grep :873
【6】执行命令同步数据
# 在目的机器上执行
# rsync -avz 用户名@源主机地址/源目录 目的目录
rsync -avz root@192.168.0.113:/opt/nfsdata/* /opt/nfsdata/
【7】crontab 定时同步
# 配置crontab, 每五分钟同步一次,这种方式不好
*/5 * * * * rsync -avz root@192.168.0.113:/opt/nfsdata/* /opt/nfsdata/
【温馨提示】crontab 定时同步数据不太好,可以使用
rsync+inotify
做数据实时同步,这里篇幅有点长了,先不讲,如果后面有时间会出一篇单独文章来讲。
6)创建 nfs provisioner 和持久化存储 SC
【温馨提示】这里跟我之前的文章有点不同,之前的方式也不适用新版本。
GitHub 地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
helm 部署 nfs-subdir-external-provisioner
1、添加 helm 仓库
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
2、helm 安装 nfs provisioner
【温馨提示】默认镜像是无法访问的,这里使用 dockerhub 搜索到的镜像
willdockerhub/nfs-subdir-external-provisioner:v4.0.2
,还有就是 StorageClass 不分命名空间,所有在所有命名空间下都可以使用。
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--namespace=nfs-provisioner \
--create-namespace \
--set image.repository=willdockerhub/nfs-subdir-external-provisioner \
--set image.tag=v4.0.2 \
--set replicaCount=2 \
--set storageClass.name=nfs-client \
--set storageClass.defaultClass=true \
--set nfs.server=192.168.0.120 \
--set nfs.path=/opt/nfsdata
【温馨提示】上面 nfs.server 设置为 VIP,可实现高可用。
3、查看
kubectl get pods,deploy,sc -n nfs-provisioner
7)部署 Harbor(Https 方式)
1、创建 Namespace
kubectl create ns harbor
2、创建证书秘钥
kubectl create secret tls myharbor.com --key myharbor.com.key --cert myharbor.com.crt -n harbor
kubectl get secret myharbor.com -n harbor
3、添加 Chart 库
helm repo add harbor https://helm.goharbor.io
4、通过 helm 安装 harbor
helm install myharbor --namespace harbor harbor/harbor \
--set expose.ingress.hosts.core=myharbor.com \
--set expose.ingress.hosts.notary=notary.myharbor.com \
--set-string expose.ingress.annotations.'nginx\.org/client-max-body-size'="1024m" \
--set expose.tls.secretName=myharbor.com \
--set persistence.persistentVolumeClaim.registry.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.jobservice.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.database.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.redis.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.trivy.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.chartmuseum.storageClass=nfs-client \
--set persistence.enabled=true \
--set externalURL=https://myharbor.com \
--set harborAdminPassword=Harbor12345
这里稍等一段时间在查看资源状态
kubectl get ingress,svc,pods,pvc -n harbor
5、ingress 没有 ADDRESS 问题解决
【分析】,发现"error: endpoints “default-http-backend” not found"
cat << EOF > default-http-backend.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: default-http-backend
labels:
app: default-http-backend
namespace: harbor
spec:
replicas: 1
selector:
matchLabels:
app: default-http-backend
template:
metadata:
labels:
app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissible as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4
# image: gcr.io/google_containers/defaultbackend:1.4
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: harbor
labels:
app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: default-http-backend
EOF
kubectl apply -f default-http-backend.yaml
6、卸载重新部署
# 卸载
helm uninstall myharbor -n harbor
kubectl get pvc -n harbor| awk 'NR!=1{print $1}' | xargs kubectl delete pvc -n harbor
# 部署
helm install myharbor --namespace harbor harbor/harbor \
--set expose.ingress.hosts.core=myharbor.com \
--set expose.ingress.hosts.notary=notary.myharbor.com \
--set-string expose.ingress.annotations.'nginx\.org/client-max-body-size'="1024m" \
--set expose.tls.secretName=myharbor.com \
--set persistence.persistentVolumeClaim.registry.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.jobservice.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.database.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.redis.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.trivy.storageClass=nfs-client \
--set persistence.persistentVolumeClaim.chartmuseum.storageClass=nfs-client \
--set persistence.enabled=true \
--set externalURL=https://myharbor.com \
--set harborAdminPassword=Harbor12345
5、访问 harbor
https://myharbor.com
账号/密码:admin/Harbor12345
6、harbor 常见操作
【1】创建项目 bigdata
【2】配置私有仓库
在文件/etc/docker/daemon.json
添加如下内容:
"insecure-registries":["https://myharbor.com"]
重启 docker
systemctl restart docker
【3】服务器上登录 harbor
docker login https://myharbor.com
#账号/密码:admin/Harbor12345
【4】打标签并把镜像上传到 harbor
docker tag rancher/pause:3.6 myharbor.com/bigdata/pause:3.6
docker push myharbor.com/bigdata/pause:3.6
7、修改 containerd 配置
以前使用 docker-engine 的时候,只需要修改/etc/docker/daemon.json 就行,但是新版的 k8s 已经使用 containerd 了,所以这里需要做相关配置,要不然 containerd 会失败。证书(ca.crt
)可以在页面上下载:
创建域名目录
mkdir /etc/containerd/myharbor.com
cp ca.crt /etc/containerd/myharbor.com/
配置文件:/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."myharbor.com".tls]
ca_file = "/etc/containerd/myharbor.com/ca.crt"
[plugins."io.containerd.grpc.v1.cri".registry.configs."myharbor.com".auth]
username = "admin"
password = "Harbor12345"
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."myharbor.com"]
endpoint = ["https://myharbor.com"]
重启 containerd
#重新加载配置
systemctl daemon-reload
#重启containerd
systemctl restart containerd
简单使用
# 把docker换成crictl 就行,命令都差不多
crictl pull myharbor.com/bigdata/mysql:5.7.38
执行 crictl 报如下错误的解决办法
WARN[0000] image connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
ERRO[0000] unable to determine image API version: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory"
这个报错是 docker 的报错,这里没使用,所以这个错误不影响使用,但是还是解决好点,解决方法如下:
cat <<EOF> /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
再次拉取镜像
crictl pull myharbor.com/bigdata/mysql:5.7.38
Kubernetes(k8s)最新版最完整版基础环境部署+master 高可用实现详细步骤就到这里了,有疑问的小伙伴欢迎给我留言哦~