k8s 部署 ruoyi 前后端分离项目

本文视频版

https://www.bilibili.com/video/BV17ugkePEeN

参考

https://blog.csdn.net/qq_50247813/article/details/136934090
https://gitee.com/nasaa/RuoYi-Vue-cloud
https://www.itsgeekhead.com/tuts/kubernetes-129-ubuntu-22-04-3/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://github.com/Joxit/docker-registry-ui/issues/140

前置条件

三台虚拟机:

hostnameip作用
node80192.168.10.80k8s 节点,控制平面
node81192.168.10.81k8s 节点
node82192.168.10.82k8s 节点
node84192.168.10.84镜像仓库

三台虚拟机都配置了主机名和 ip 的映射,windows 也配置了主机名到 ip 的映射。
三台虚拟机都能访问互联网,最好能访问国外仓库。

安装 k8s

确保 k8s 在启动时加载内核模块 overlaybr_netfilter两个内核模块:

printf "overlay\nbr_netfilter\n" >> /etc/modules-load.d/containerd.conf

立即加载 overlaybr_netfilter 内核模块:

modprobe overlay
modprobe br_netfilter

配置 k8s 的网络:

printf "net.bridge.bridge-nf-call-iptables = 1\nnet.ipv4.ip_forward = 1\nnet.bridge.bridge-nf-call-ip6tables = 1\n" >> /etc/sysctl.d/99-kubernetes-cri.conf

image.png
重新加载配置:

sysctl --system

image.png
安装 containerd:

wget https://github.com/containerd/containerd/releases/download/v1.7.13/containerd-1.7.13-linux-amd64.tar.gz -P /opt/software/
tar Cxzvf /usr/local /opt/software/containerd-1.7.13-linux-amd64.tar.gz
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -P /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now containerd

安装 runc:

wget https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64 -P /opt/software/
install -m 755 /opt/software/runc.amd64 /usr/local/sbin/runc

image.png
安装 cni 网络插件:

wget https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz -P /opt/software/
mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin /opt/software/cni-plugins-linux-amd64-v1.4.0.tgz

修改 containerd 的配置并重启 containerd:

mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
vim /etc/containerd/config.toml
# 修改 SystemdCgroup 配置项的值为 truesystemctl restart containerd

关闭 swap:

vim /etc/fstab

注释掉最后一行:
image.png
更新 apt-get 并信任 k8s 官网链接:

apt-get update
apt-get install -y apt-transport-https ca-certificates curl gpgmkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.listapt-get update

重启:

reboot

下载 k8s 软件包:

apt-get install -y kubelet=1.29.1-1.1 kubeadm=1.29.1-1.1 kubectl=1.29.1-1.1
apt-mark hold kubelet kubeadm kubectl

apt-mark hold kubelet kubeadm kubectl 命令的作用是将 kubeletkubeadmkubectl 这三个软件包标记为“保留”状态。这意味着这些软件包不会被系统自动升级或删除

检查 swap 是否关闭,确保 swap 是 0:

free -m

下面这些步骤仅仅需要在控制平面节点执行:

# 这个命令会比较耗时
kubeadm init --pod-network-cidr 10.10.0.0/16 --kubernetes-version 1.29.1 --node-name node80export KUBECONFIG=/etc/kubernetes/admin.conf# add Calico 3.27.2 CNI 
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/tigera-operator.yaml
wget https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/custom-resources.yaml
# 将 CIDR 配置为 10.10.0.0/16
vim custom-resources.yaml
kubectl apply -f custom-resources.yaml# 获取 worker 节点加入到集群的命令
kubeadm token create --print-join-command

image.png

在 worker 节点执行上面获取到的将 worker 节点加入到集群的命令将当前节点加入到 k8s 集群中:

kubeadm join 192.168.10.80:6443 --token pecvqm.rlxcsywbvm2resvv \--discovery-token-ca-cert-hash sha256:fac6cb7a265dc30d7560517dc64debaf933592215a58a8912453f6a56bde7701

–pod-network-cidr 明确了 Kubernetes 集群中 Pod 网络的 IP 地址范围

安装镜像仓库 registry

安装 htpasswd 工具:

sudo apt-get update
sudo apt-get install apache2-utils

创建挂载容器的目录以及密码文件:

mkdir -p /docker/volume/registry/auth/
htpasswd -Bc /docker/volume/registry/auth/htpasswd root
# 输入 root 的密码

创建 registry 容器挂载数据的目录:

mkdir -p /docker/volume/registry/data

创建 registry 挂载配置文件的目录,并创建配置文件:

mkdir -p /docker/volume/registry/conf
vim /docker/volume/registry/conf/config.yml
version: 0.1
log:level: debugfields:service: registryenvironment: production
storage:filesystem:rootdirectory: /var/lib/registry
http:addr: :5000headers:Access-Control-Allow-Origin: ['http://node84:8080','http://192.168.10.84']Access-Control-Allow-Methods: ['HEAD', GET', 'OPTIONS', 'DELETE', 'POST', 'PUT']Access-Control-Allow-Headers: ['Authorization','Accept']http2:disabled: false
auth:htpasswd:realm: basic-realmpath: /auth/htpasswd

创建 docker 网络:

docker network create registry-net

启动 registry 容器:

docker run -d \--name registry \--network registry-net \-v /docker/volume/registry/auth:/auth \-v /docker/volume/registry/data:/var/lib/registry \-v /docker/volume/registry/conf/config.yml:/etc/docker/registry/config.yml \-e REGISTRY_AUTH=htpasswd \-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \-e REGISTRY_HTTP_SECRET=secretkey \-p 5000:5000 \registry:2

修改 containerd 的配置,将 registry 的地址添加到镜像仓库列表中:

mkdir -p /etc/containerd/certs.d/node84:5000tee /etc/containerd/certs.d/node84:5000/hosts.toml << 'EOF'
server = "http://node84:5000"[host."http://node84:5000"]capabilities = ["pull", "resolve", "push"]skip_verify = true
EOFsystemctl restart containerd.service

因为我们需要将 docker 上的镜像推送到 registry 中,所以,也需要修改 docker 的配置,添加我们的 registry 镜像仓库的地址。
将 node84 添加到 docker 的安全镜像仓库名单中,避免使用 docker 推送镜像到 registry 中报错,将 “insecure-registries”: [“192.168.56.10:5000”]’ 加入到 /etc/docker/daemon.json 中,再使用 systemctl restart docker 重启 Docker 就可以了。

{"insecure-registries": ["node84:5000"]
}

安装 registry 可视化工具

启动一个 registry-browser 容器并连接到自定义网络:

docker run -d \--name registry-browser \--network registry-net \-e REGISTRY_TITLE="Docker Registry Browser" \-e NGINX_PROXY_PASS_URL="http://registry:5000" \-e REGISTRY_AUTH="true" \-e REGISTRY_AUTH_USER="root" \-e REGISTRY_AUTH_PASSWORD="123456" \-p 8080:80 \joxit/docker-registry-ui:latest

比较老的版本中使用 -e REGISTRY_URL=“http://registry:5000” \ 配置 registry 的地址,如果新版本中使用这个配置,在前端会出现 An error occured: Check your connection and your registry must have Access-Control-Allow-Origin header set to http://node84:8080这个异常,需要使用 NGINX_PROXY_PASS_URL 这个配置

访问主机的 8080 端口即可看到 registry 中的镜像。

部署 ruoyi 前后端分离项目

制作后端镜像

编写 Dockerfile 文件:

# 使用官方的 OpenJDK 8 镜像作为基础镜像
FROM openjdk:8-jdk-alpine
# 创建存放上传文件的目录
RUN mkdir -p /opt/project/ruoyi/ruoyi-backend/upload-file-path
# 创建存放日志的目录
RUN mkdir -p /opt/project/ruoyi/ruoyi-backend/logs
# 安装字体文件
RUN mkdir -p /etc/apk/
RUN touch /etc/apk/repositories
RUN echo -e 'https://mirrors.aliyun.com/alpine/v3.6/main/\nhttps://mirrors.aliyun.com/alpine/v3.6/community/' > /etc/apk/repositories
RUN set -xe && apk --no-cache add ttf-dejavu fontconfig
# 设置工作目录
WORKDIR /opt/project/ruoyi/ruoyi-backend
# 将构建好的 JAR 文件复制到容器中
COPY ./ruoyi-admin/target/ruoyi-admin.jar ruoyi-admin.jar
# 暴露应用程序端口
EXPOSE 8080
# 启动应用程序
CMD ["nohup","java","-jar","/opt/project/ruoyi/ruoyi-backend/ruoyi-admin.jar", ">", "/opt/project/ruoyi/ruoyi-backend/logs/nohup.log", "&"]

直接用 idea 连接到我们虚拟机中的 Docker 上,在 idea 中点击 Dockerfile 中的绿色箭头将后端打成镜像。
在虚拟机中查看镜像是否好了:

docker images

将打好的后端镜像推送到 registry 中:

#推送后端镜像
#修改镜像tag
docker tag ruoyi-backend:1.0 node84:5000/ruoyi-backend:1.0# 因为 registry 设置了用户名和密码,所以需要先登录才能推送镜像
docker login -u root -p 123456 node84:5000#推送到私有镜像仓库中
docker push node84:5000/ruoyi-backend:1.0

制作前端镜像

编写前端的 Dockerfile:

# 使用 Nginx 作为基础镜像
FROM nginx:1.12.2
# 将 nginx.conf 拷贝到容器中
COPY nginx.conf /etc/nginx/nginx.conf
# 创建存放前端编译后代码的目录
RUN mkdir -p /opt/project/ruoyi/ruoyi-front-code
# 将构建好的应用拷贝到 Nginx 的默认 web 目录
COPY dist /opt/project/ruoyi/ruoyi-front-code
# Expose 端口
EXPOSE 80
# 启动 Nginx 服务器
CMD ["nginx", "-g", "daemon off;"]

直接用 webstorm 连接到我们虚拟机中的 Docker 上,在 webstorm 中点击 Dockerfile 中的绿色箭头将后端打成镜像。
在虚拟机中查看镜像是否好了:

docker images

将打好的前端镜像推送到 registry 中:

#推送前端镜像
#修改镜像tag
docker tag ruoyi-frontend:1.0 node84:5000/ruoyi-frontend:1.0# 因为 registry 设置了用户名和密码,所以需要先登录才能推送镜像
docker login -u root -p 123456 node84:5000#推送到私有镜像仓库中
docker push node84:5000/ruoyi-frontend:1.0

k8s 部署后端

将后端初始化的两个 sql 文件创建为 configmap

将 ruoyi 后端的两个初始化 sql 文件放入 /opt/ruoyi/sql 中:

mkdir -p /opt/ruoyi/sql

切换成 k8s 的管理员:

export KUBECONFIG=/etc/kubernetes/admin.conf

这种切换方式重启后会失效,可以向 ~/.bashrc 文件末尾添加 export KUBECONFIG=/etc/kubernetes/admin.conf 后,再使用 source ~/.bashrc 使配置永久生效

使用如下命令检查是否切换成功:

kubectl cluster-info

创建一个为我们当前机器分配在 default 空间下创建 configmap 权限的配置文件:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: configmap-creator
rules:
- apiGroups: [""]resources: ["configmaps"]verbs: ["create", "update", "patch", "delete"]---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: configmap-creator-bindingnamespace: default
subjects:
- kind: Username: system:node:node80apiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: configmap-creatorapiGroup: rbac.authorization.k8s.io

使这个配置文件生效:

kubectl apply -f role-config.yaml

当前节点就有在 default 空间下创建 configmap 的权限了。
根据 ruoyi 后端的初始化 SQL 文件创建 configMap:

注意:sql 文件头部要加上:use ry-vue; SET NAMES utf8;

kubectl create configmap ruoyi-init-sql-config-map --from-file=/opt/ruoyi/sql
# 查看这个 configmap 的详情
kubectl describe configmap/ruoyi-init-sql-config-map

将需要修改的后端配置创建为 configmap

后端的镜像中,application.yaml 配置文件中 MySQL 和 Redis 的地址都是写死的,需要我们根据要求创建在 k8s 中使用的 configMap。
拷贝一份 application.yaml 配置文件,将其中的 ip 地址改为对应 service 的服务名地址:

# 数据源配置
spring:redis:# 地址host: ruoyi-redis-service# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password: 123456# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最大空闲连接max-idle: 8# 连接池的最大数据库连接数max-active: 8# #连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1msdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主库数据源master:url: jdbc:mysql://ruoyi-mysql-service:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&connectTimeout=1000&socketTimeout=30000&autoReconnect=true&failOverReadOnly=falseusername: rootpassword: 123456# 从库数据源slave:# 从数据源开关/默认关闭enabled: falseurl:username:password:# 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置连接超时时间connectTimeout: 30000# 配置网络超时时间socketTimeout: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsewebStatFilter:enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /druid/*# 控制台管理用户名和密码login-username: ruoyilogin-password: 123456filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: true

根据这个配置文件生成 configMap:

kubectl create configmap ruoyi-admin-config --from-file=/opt/ruoyi/application-k8s.yaml
kubectl describe configmap/ruoyi-admin-config

将 redis 服务的配置 redis.conf 创建为 configmap

下载需要的 redis 对应版本,解压后拷贝 redis.conf 文件,修改配置文件中的如下部分:

# 注释掉 bind 127.0.0.1,bind 用于限制访问 Redis 的机器 ip,直接关掉
# bind 127.0.0.1# 修改 daemonize no 为 yes,让 Redis 可以后台启动
daemonize yes# 设置密码
requirepass 123456

根据这个 redis.conf 配置文件生成 configMap:

kubectl create configmap ruoyi-redis-config-map --from-file=/opt/ruoyi/redis.conf
kubectl describe configmap/ruoyi-redis-config-map

将 registry 的用户名和密码创建为 secret

创建一个 secret 用于存储我们的 registry 仓库的用户名和密码,在 k8s 资源编排 yaml 文件中,在 deployment 中使用 imagePullSecrets 字段就可以引用这个 Secret 对象,这样 Kubernetes 就可以在拉取镜像时使用这个 Secret 对象中的认证信息。

kubectl create secret registry-user-pwd-secret \--docker-server=http://node84:5000 \--docker-username=root \--docker-password=123456

containerd 添加 registry 镜像仓库地址

因为我们使用的 registry 是 http 协议,containerd 默认认为是不安全的,需要做如下配置,修改 containerd 的配置,使得 containerd 从 registry 拉取镜像不会报错:
image.png

[plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."node84:5000"]endpoint = ["http://node84:5000"]

注意:上面的 node84 是 registry 的地址,如果 registry 地址不是 node84,两个 node84 都需要更改为你的 registry 的地址,所有 k8s 机器都需要修改

sudo systemctl restart containerd

部署后端服务

后端部署的 k8s 资源清单:

# 数据库
apiVersion: apps/v1
kind: Deployment
metadata:name: databasenamespace: default
spec:selector:matchLabels:app: databasetemplate:metadata:labels:app: databasespec:containers:- name: databaseimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalue: "123456"- name: MYSQL_DATABASEvalue: "ry-vue"volumeMounts:- mountPath: /docker-entrypoint-initdb.dname: ruoyi-init-sqlresources:limits:memory: "512Mi"cpu: "500m"ports:- containerPort: 3306volumes:- name: ruoyi-init-sqlconfigMap:name: ruoyi-init-sql-config-mapimagePullSecrets:- name: registry-user-pwd-secret---
apiVersion: v1
kind: Service
metadata:name: ruoyi-mysql-servicenamespace: default
spec:selector:app: databaseports:- port: 3306targetPort: 3306---
# redis
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- name: redisimage: redis:7.2.0resources:limits:memory: "512Mi"cpu: "500m"ports:- containerPort: 6379volumeMounts:- mountPath: /usr/local/etc/redis/redis.confname: ruoyi-redis-configvolumes:- name: ruoyi-redis-configconfigMap:name: ruoyi-redis-config-mapimagePullSecrets:- name: registry-user-pwd-secret---
apiVersion: v1
kind: Service
metadata:name: ruoyi-redis-servicenamespace: default
spec:selector:app: redisports:- port: 6379targetPort: 6379# ruoyi 后端
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ruoyi-java
spec:replicas: 2selector:matchLabels:app: ruoyi-javatemplate:metadata:labels:app: ruoyi-javaspec:initContainers:- name: wait-for-mysqlimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalue: "123456"command:- sh- -c- |set -emaxTries=10while [ "$$maxTries" -gt 0 ] \&& ! mysqladmin ping --connect-timeout=3 -s \-hruoyi-mysql-service -uroot -p$$MYSQL_ROOT_PASSWORDdo echo 'Waiting for MySQL to be available'sleep 5let maxTries--doneif [ "$$maxTries" -le 0 ]; thenecho >&2 'error: unable to contact MySQL after 10 tries'exit 1fi- name: wait-for-redisimage: redis:7.2.0env:- name: REDIS_PASSWORDvalue: "123456"command:- sh- -c- |set -emaxTries=10while [ "$$maxTries" -gt 0 ] \&& ! timeout 3 redis-cli -h ruoyi-redis-service -a $$REDIS_PASSWORD pingdo echo 'Waiting for Redis to be available'sleep 5let maxTries--doneif [ "$$maxTries" -le 0 ]; thenecho >&2 'error: unable to contact Redis after 10 tries'exit 1ficontainers:- name: ruoyi-javaimage: node84:5000/ruoyi-backend:1.0resources:limits:memory: "512Mi"cpu: "512m"imagePullPolicy: Alwaysports:- containerPort: 8080# /app/ruoyi/ 是 dockerfile 中拷贝 jar 包所到的目录# springboot 启动时,会从 jar 包所在的目录的 config 子目录中查找配置文件volumeMounts:- mountPath: /opt/project/ruoyi/ruoyi-backend/configname: config# 使用 application-k8s.yaml 作为配置文件args:["java", "-jar", "ruoyi-admin.jar", "--spring.profiles.active=k8s"]volumes:- name: configconfigMap:name: ruoyi-admin-configimagePullSecrets:- name: registry-user-pwd-secret
---
apiVersion: v1
kind: Service
metadata:name: ruoyi-backend-servicenamespace: default
spec:selector:app: ruoyi-javaports:- port: 8080targetPort: 8080

根据资源清单部署后端:

kubectl apply -f ruoyi-k8s-backend.yaml

k8s 部署前端

将前端的 nginx.conf 创建为 configmap

Nginx 的配置文件:

server {listen       80;server_name  localhost;charset utf-8;location / {# dockerfile中WORKDIR目录root   /opt/project/ruoyi/ruoyi-front-code;try_files $uri $uri/ /index.html;index  index.html index.htm;}location /prod-api/ {proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 后端 service 的 DNSproxy_pass http://ruoyi-backend-service.default:8080/;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}
}

根据 Nginx 配置文件创建 configMap:

kubectl create configmap ruoyi-ui-config --from-file=/opt/ruoyi/nginx.conf
kubectl describe configmap/ruoyi-ui-config

部署前端服务

前端部署的 k8s 资源清单:

apiVersion: apps/v1
kind: Deployment
metadata:name: ruoyi-nginx
spec:replicas: 1selector:matchLabels:app: ruoyi-nginxtemplate:metadata:labels:app: ruoyi-nginxspec:initContainers:- name: wait-for-ruoyi-backend-serviceimage: alpinecommand:- sh- -c- |apk add --no-cache curlecho "Starting to wait for ruoyi-backend-service..."until curl -s -f -m 3 http://ruoyi-backend-service:8080doecho "Waiting for ruoyi-backend-service...";sleep 5;doneecho "ruoyi-backend-service is available now."containers:- name: ruoyi-nginximage: node84:5000/ruoyi-frontend:1.0resources:limits:memory: "512Mi"cpu: "512m"imagePullPolicy: Alwaysports:- containerPort: 80volumeMounts:- mountPath: /etc/nginx/conf.dname: configvolumes:- name: configconfigMap:name: ruoyi-ui-configitems:- key: nginx.confpath: default.confimagePullSecrets:- name: registry-user-pwd-secret---
apiVersion: v1
kind: Service
metadata:name: ruoyi-fronted-servicenamespace: default
spec:type: NodePortselector:app: ruoyi-nginxports:- port: 80targetPort: 80nodePort: 30000

根据资源清单启动前端:

kubectl apply -f ruoyi-k8s-fronted.yaml

前端通过 nodePort 暴露出去了,访问任意 k8s 节点的 30000 端口即可访问前端。

遇到的问题

拉取镜像失败

只要出现这种情况:

ctr: failed to copy: httpReadSeeker: failed open: failed to do request: Get "https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/52/52d2b7f179e32b4cbd579ee3c4958027988f9a8274850ab0c7c24661e3adaac5/data?verify=1719112771-ZRsD38JmAnzgLW0YPDJ4BVoEmvw%3D": dial tcp 162.220.12.226:443: connect: connection refused

就是网络不通,需要开代理。
可以使用如下命令测试拉取镜像是否能成功:

sudo ctr images pull docker.io/library/redis:7.2.0

可以配置 containerd 使用阿里云的镜像仓库加速:

vim /etc/containerd/config.toml
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."node63:5000"]endpoint = ["http://node63:5000"][plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://6zemac9k.mirror.aliyuncs.com"]

修改后重启 containerd:

sudo systemctl restart containerd

配置完后,拉取镜像的时候并没有从 aliyun 拉取,不知道为什么。
最后我还是选择了使用代理。

拉取前后端镜像失败

containerd 的配置 /etc/containerd/config.toml 中:
[plugins.“io.containerd.grpc.v1.cri”.registry.mirrors]
[plugins.“io.containerd.grpc.v1.cri”.registry.mirrors.“node63:5000”]
endpoint = [“http://node63:5000”]
[plugins.“io.containerd.grpc.v1.cri”.registry.mirrors.“docker.io”]
endpoint = [“https://6zemac9k.mirror.aliyuncs.com”]

registry.mirrors.“node63:5000” 之前因为忘了修改,应该要改成现在的 registry 的地址 node63:5000。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/32982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【漏洞复现】畅捷通T+ keyEdit.aspx SQL漏洞

0x01 产品简介 畅捷通 T 是一款灵动&#xff0c;智慧&#xff0c;时尚的基于互联网时代开发的管理软件&#xff0c;主要针对中小型工贸与商贸企业&#xff0c;尤其适合有异地多组织机构(多工厂&#xff0c;多仓库&#xff0c;多办事处&#xff0c;多经销商)的企业&#xff0c;…

用户态协议栈06-TCP三次握手

最近由于准备软件工程师职称考试&#xff0c;然后考完之后不小心生病了&#xff0c;都没写过DPDK的博客了。今天开始在上次架构优化的基础上增加TCP的协议栈流程。 什么是TCP 百度百科&#xff1a;TCP即传输控制协议&#xff08;Transmission Control Protocol&#xff09;是…

LabVIEW程序退出后线程仍在运行问题

LabVIEW程序退出后&#xff0c;线程仍在运行的问题可能源于资源管理不当、未正确终止循环、事件结构未处理、并发编程错误以及外部库调用未结束等方面。本文将从这些角度详细分析&#xff0c;探讨可能的原因和解决方案&#xff0c;并提供预防措施&#xff0c;帮助开发者避免类似…

将知乎专栏文章转换为 Markdown 文件保存到本地

一、参考内容 参考知乎文章代码 | 将知乎专栏文章转换为 Markdown 文件保存到本地&#xff0c;利用代码为GitHub&#xff1a;https://github.com/chenluda/zhihu-download。 二、步骤 1.首先安装包flask、flask-cors、markdownify 2. 运行app.py 3.在浏览器中打开链接&…

已解决javax.management.BadStringOperationException异常的正确解决方法,亲测有效!!!

已解决javax.management.BadStringOperationException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 分析错误日志 检查字符串值合法性 确认字符串格式 优化代码逻辑 增加…

Trimesh介绍及基本使用

Trimesh介绍及基本使用 Trimesh是一个纯Python 工具库&#xff08;支持3.7版本以上&#xff09;&#xff0c;用于加载和使用三角形Mesh网格&#xff0c;支持多种常见的三维数据格式&#xff0c;如二进制/文本格式的STL、Wavefront OBJ、二进制/文本格式的PLY、GLTF/GLB 2.0、3…

Leetcode 2713. 矩阵中严格递增的单元格数(DFS DP)

Leetcode 2713. 矩阵中严格递增的单元格数 DFS 容易想到&#xff0c;枚举每个点作为起点&#xff0c;向同行同列的可跳跃点dfs&#xff0c;维护全局变量记录可达的最远距离 超时&#xff0c;通过样例193 / 566 class Solution {int res 0;public void dfs(int[][] mat, in…

EtherCAT笔记(三) —— 主站与从站的硬件组成

1. EtherCAT 主站的硬件组成 EtherCAT主站使用标准以太网控制器&#xff0c;也即EtherCAT主站可以使用以太网控制器的任何设备。当我们有一台带网口的笔记本、工控机&#xff0c;甚至是树莓派也可以作为EtherCAT主站。 EtherCAT协议是对Ethernet协议在实时控制等方面的优化&am…

android关于源码编译简单的apk处理

文章目录 简述文件的添加 简述 创建AOSP源码可编译一个简单apk的过程&#xff0c;代码子目录结构图如下所示 文件的添加 1.com.custom.test目录下创建TestActivity.java文件 用于简单的界面显示类 package com.custom.test;import android.app.Activity; import android.o…

高考填报志愿不容易,压线考生怎么救?

每年的高考季 就是高考生们水深火热的一大月份&#xff0c;很多考生都会纠结要报考哪些学校&#xff0c;哪些专业好&#xff0c;并非每个学生从小就有明确的目标&#xff0c;很多人到6月份才深思这个问题&#xff0c;此时难免手慌脚乱&#xff0c;更别说一些考生的分数处于一本…

创建第一个Springboot项目(环境准备、环境存在的问题、启动时存在的问题、启动的方式)

一、环境准备 专业版创建springboot&#xff0c;直接有一个选项可以选择 社区版&#xff0c;需要下载一个spring的插件 不要直接点 install 因为这个插件是付费的&#xff0c;直接点安装只有30天使用期限 在里面找免费版本的下载 然后安装 安装完成后&#xff0c;这个插件名会变…

利用ChatGPT辅助撰写课题申报书中的研究框架与内容设计全攻略指南

欢迎关注EssayBot&#xff0c;为大家带来最酷最有效的智能AI学术科研写作攻略。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥沟通&#xff1a;yida985 撰写课题申报书是启动科研项目的第一个步骤&#xff0c;而研究框架与内容设计又是这一过程中的关键要素&#xff0…

基于YOLOv5的PCB板缺陷检测系统的设计与实现(PyQT页面+YOLOv5模型+数据集)

简介 随着电子设备的广泛应用,PCB(印刷电路板)作为其核心部件,其质量和可靠性至关重要。然而,PCB生产过程中常常会出现各种缺陷,如鼠咬伤、开路、短路、杂散、伪铜等。这些缺陷可能导致设备故障,甚至引发严重的安全问题。为了提高PCB检测的效率和准确性,我们基于YOLOv…

Go 三色标记法:一种高效的垃圾回收策略

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

C++基础知识——引用

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

让你的Python代码更简洁:一篇文章带你了解Python列表推导式

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 列表推导式 📒📝 语法📝 条件筛选📝 多重循环📝 列表推导式的优点📝 使用场景📝 示例代码🎯 示例1🎯 示例2⚓️ 相关链接 ⚓️📖 介绍 📖 在Python编程中,列表推导式是一种强大且高效的语法,它允许你用…

Java程序之素数问题

题目&#xff1a; 判断101-200之间有多少个素数&#xff0c;并输出所有素数。 程序分析&#xff1a; 判断素数的方法&#xff1a;用一个数分别去除2到sqrt(这个数)&#xff0c;如果能被整除&#xff0c;则表明此数不是素数&#xff0c;反之是素数。素数被利用在密码学上&#…

算法设计与分析 笔记

截图摘自湖南大学彭鹏老师的ppt。笔记也是根据他的ppt整理的。 动态规划 核心 用数组记录中间结果&#xff0c;避免重复计算 三角数塔问题 问题描述 给定一个三角形数塔&#xff0c;从顶部出发&#xff0c;每次只能移动到下一行的相邻元素。要求找到一条路径&#xff0c;…

VS Code安装及环境配置(超详细)

VS Code简介 Visual Studio Code&#xff08;简称 VS Code &#xff09;是 Microsoft 于2015年4月发布的一款代码编辑器&#xff0c;以界面简洁、轻量著称。 它是一款免费开源的现代化轻量级代码编辑器&#xff0c;支持几乎所有主流开发语言的语法高亮、智能代码补全、自定义…

【HTTPS云证书部署】SpingBoot部署证书

这里以华为云证书为例。 1. 下载证书 2. 解压 3. 选择.top_Tomcat复制到SpringBoot的Resource/source下 4. 在.properties文件中进行配置 修改key-store和key-store-password