二进制部署k8s

k8s二进制部署

关闭防火墙

bash 复制代码
systemctl stop firewalld && systemctl disable firewalld

关闭swap

bash 复制代码
#关闭swap (暂时关闭)
swapoff -a
#直接注掉swap那行 (永久关闭)
vi /etc/fstab  
#查看swap状态
free -m

高可用集群部署

1. CA证书(任意节点)

1.1 安装cfssl

cfssl是非常好用的CA工具,我们用它来生成证书和秘钥文件

安装过程比较简单,如下:

下载或者直接从本地拷贝可执行文件到 /usr/bin/ 下

$ mkdir -p ~/bin

$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl

$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/bin/cfssljson

修改为可执行权限

$ chmod +x /usr/bin/cfssl /usr/bin/cfssljson

验证,会显示版本等信息

$ cfssl version

注意:接下来文件路径中的target泛指 pki目录的父级目录!!!!!!!!!!!!!!!

1.2 生成根证书

根证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。

bash 复制代码
# 生成证书和私钥
$ cd target/pki
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca

# 生成完成后会有以下文件(我们最终想要的就是ca-key.pem和ca.pem,一个秘钥,一个证书)
$ ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

# 创建目录,为所有节点创建目录,如在26机器上控制62创建目录:26机器上执行 ssh root@192.168.51.26 "mkdir -p /etc/kubernetes/pki/"
$ ssh <user>@<node-ip> "mkdir -p /etc/kubernetes/pki/"

# 分发到每个主节点,这里主要是涉及多个master节点,如果单个master节点,可以不用分发;如果分发到node节点,也不会影响集群
$ scp ca*.pem <user>@<node-ip>:/etc/kubernetes/pki/

2. 部署etcd集群(master节点)

注意:etcd集群部署的时候包含主节点,强烈建议部署etcd的个数为奇数如:3,5,7等;如无特殊要求,正常情况下,3个即可满足。

2.1 下载etcd

如果你是从网盘下载的二进制可以跳过这一步(网盘中已经包含了etcd,不需要另外下载);没有从网盘下载bin文件的话需要自己下载etcd

下载安装方式如下,本文默认用户拥有离线安装包

$ wget https://github.com/coreos/etcd/releases/download/v3.2.18/etcd-v3.2.18-linux-amd64.tar.gz

离线安装包方式:
$ tar xf etcd-v3.2.20-linux-amd64.tar.gz
$ cd etcd-v3.2.20-linux-amd64
$ cp etcd etcdctl /usr/bin/

#### 2.2 生成etcd证书和私钥
​```bash
# 生成证书、私钥  (修改etcd-csr.json)
$ cd target/pki/etcd
$ cfssl gencert -ca=../ca.pem \
    -ca-key=../ca-key.pem \
    -config=../ca-config.json \
    -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

# 分发到每个etcd节点
$ scp etcd*.pem <user>@<node-ip>:/etc/kubernetes/pki/
2.3 创建service文件

注意:安装提供service模板,只需修改相关参数即可 (etcd.service)

bash 复制代码
# scp配置文件到每个etcd节点
$ scp target/services/etcd.service <user>@<node-ip>:/etc/systemd/system/

# 为每一个etcd节点创建数据和工作目录
$ ssh <user>@<node-ip> "mkdir -p /var/lib/etcd"
2.4 启动服务

etcd 进程首次启动时会等待其它节点的 etcd 加入集群,

为每一个etcd节点启动命令,

$ systemctl start etcd

卡住一段时间,为正常现象。

bash 复制代码
#启动服务
$ systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd
#查看etcd集群状况
$ etcdctl --endpoint=https://192.168.55.36:2379     --ca-file=/etc/kubernetes/pki/ca.pem --cert-file=/etc/kubernetes/pki/etcd.pem --key-file=/etc/kubernetes/pki/etcd-key.pem  member list
#查看状态
$ service etcd status
#查看启动日志
$ journalctl -f -u etcd

3. 部署api-server(master节点)

修改apiserver 下的kubernetes-csr.json 文件

bash 复制代码
"hosts"[
	"127.0.0.1",
	"192.168.126.130",
	"10.254.0.1",			-----这个必须加
	"kubernetes.default.svc",
	``````````
	``````
	
3.1 生成证书和私钥
bash 复制代码
# 生成证书、私钥
$ cd target/pki/apiserver
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

# 分发到每个节点
$ scp kubernetes*.pem <user>@<node-ip>:/etc/kubernetes/pki/
3.2 创建service文件

注意:service模板修改参数!!!!!!!

bash 复制代码
# 配置apiserver服务文件   (在kube -api 文件夹下)
$ vim kube-apiserver.service

分发
scp target/services/kube-apiserver.service <user>@<node-ip>:/etc/systemd/system/

将kubernetes-bin-linux-x86_64-1.17.5下的所有文件拖到 /usr/bin/下
并加上可执行权限
chmod +x /usr/bin/kube*

# 创建日志目录
$ mkdir -p /var/log/kubernetes
3.3 启动服务
bash启动服务 复制代码
$ systemctl restart kube-apiserver
查看状态
$ systemctl status kube-apiserver
#启动服务
$ systemctl daemon-reload && systemctl enable kube-apiserver && systemctl restart kube-apiserver

提示:启动服务可能提示token.csv未找到,导致服务无法启动,需要添加token.csv文件
需要将token.csv复制到/etc/kubernetes
token.csv文件中的token是在主节点上生成的,本部署文档提供token.csv模板,只需替换token.csv文件第一行第一个token串即可。
在主节点执行  head -c 16 /dev/urandom | od -An -t x | tr -d ' '
生成字符串

#查看运行状态
$ service kube-apiserver status
#查看日志
$ journalctl -f -u kube-apiserver
#检查监听端口
$ netstat -ntlp

5. 部署kubectl(任意节点) (修改kube.config kubelet-bootsrap.kubeconfig)

注意:强烈建议在主节点!!!!!!!!!!

kubectl 是 kubernetes 集群的命令行管理工具,它默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息。

5.1 创建 admin 证书和私钥

kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。

kubectl 作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的 admin 证书。

bash 复制代码
# 创建证书、私钥
$ cd target/pki/admin
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes admin-csr.json | cfssljson -bare admin
5.2 创建kubeconfig配置文件

kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书

bash 复制代码
# 设置集群参数 此处为主节点ip+安全端口6443
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://192.168.10.178:6443 \
  --kubeconfig=kube.config

# 设置客户端认证参数
$ kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kube.config

# 设置上下文参数
$ kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kube.config
  
# 设置默认上下文
$ kubectl config use-context kubernetes --kubeconfig=kube.config

# 分发到目标节点
注意:为所有节点创建目录,然后在分发配置文件:(所有节点!!!!)
$ mkdir /root/.kube
$ scp kube.config <user>@<node-ip>:~/.kube/config
5.3 授予 kubernetes 证书访问 kubelet API 的权限

在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,授权 apiserver 调用 kubelet API。

bash 复制代码
$ kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
5.4 小测试
bash 复制代码
# 查看集群信息
$ kubectl cluster-info
$ kubectl get all --all-namespaces
$ kubectl get componentstatuses

6. 部署controller-manager(master节点) (改两个文件,controller-manager.kubeconfig这个文件不改也没事)

controller-manager启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

6.1 创建证书和私钥
bash 复制代码
# 生成证书、私钥
$ cd target/pki/controller-manager
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes controller-manager-csr.json | cfssljson -bare controller-manager
# 分发到每个master节点,只有一个主节点不分发,修改模板文件即可
$ scp controller-manager*.pem <user>@<node-ip>:/etc/kubernetes/pki/
6.2 创建controller-manager的kubeconfig
bash 复制代码
# 创建kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://192.168.10.178:6443 \
  --kubeconfig=controller-manager.kubeconfig

$ kubectl config set-credentials system:kube-controller-manager \
  --client-certificate=controller-manager.pem \
  --client-key=controller-manager-key.pem \
  --embed-certs=true \
  --kubeconfig=controller-manager.kubeconfig

$ kubectl config set-context system:kube-controller-manager \
  --cluster=kubernetes \
  --user=system:kube-controller-manager \
  --kubeconfig=controller-manager.kubeconfig

$ kubectl config use-context system:kube-controller-manager --kubeconfig=controller-manager.kubeconfig

# 分发controller-manager.kubeconfig  只有一个主节点,可以不分发,将其拷贝到/etc/kubernetes/即可!(该文件不做修改)
$ scp controller-manager.kubeconfig <user>@<node-ip>:/etc/kubernetes/
6.3 创建service文件 (修改kube-controller-manager.service)
bash 复制代码
# scp配置文件到每个master节点,只有一个主节点,可以不分发,将其修改后拷贝到/etc/systemd/system/
$ scp target/services/kube-controller-manager.service <user>@<node-ip>:/etc/systemd/system/
6.4 启动服务
bash 复制代码
# 启动服务
$ systemctl start kube-controller-manager
# 启动服务
$ systemctl daemon-reload && systemctl enable kube-controller-manager && systemctl restart kube-controller-manager

# 检查状态  (如果显示用户、编辑权限被禁止,正常现象,后面会给赋权)
$ service kube-controller-manager status

# 查看日志
$ journalctl -f -u kube-controller-manager

# 查看leader
$ kubectl get endpoints kube-controller-manager --namespace=kube-system -o yaml

7. 部署scheduler(master节点)

scheduler启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

7.1 创建证书和私钥
bash 复制代码
# 生成证书、私钥    (修改 kube-scheduler.kubeconfig  scheduler-csr.json)
$ cd target/pki/scheduler
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes scheduler-csr.json | cfssljson -bare kube-scheduler
7.2 创建scheduler的kubeconfig
bash 复制代码
# 创建kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://192.168.10.178:6443 \
  --kubeconfig=kube-scheduler.kubeconfig

$ kubectl config set-credentials system:kube-scheduler \
  --client-certificate=kube-scheduler.pem \
  --client-key=kube-scheduler-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-scheduler.kubeconfig

$ kubectl config set-context system:kube-scheduler \
  --cluster=kubernetes \
  --user=system:kube-scheduler \
  --kubeconfig=kube-scheduler.kubeconfig

$ kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig

# 分发kubeconfig
$ scp kube-scheduler.kubeconfig <user>@<node-ip>:/etc/kubernetes/
7.3 创建service文件
bash 复制代码
# scp配置文件到每个master节点,
注: 主节点只有一个情况下,只需要修改模板,并复制到/etc/systemd/system/,不需要分发  (修改 kube-scheduler.service)
$ scp target/services/kube-scheduler.service <user>@<node-ip>:/etc/systemd/system/
7.4 启动服务
bash 复制代码
# 启动服务
$ systemctl start kube-scheduler
# 启动服务
$ systemctl daemon-reload && systemctl enable kube-scheduler && systemctl restart kube-scheduler
# 检查状态
$ service kube-scheduler status


# 查看日志
$ journalctl -f -u kube-scheduler
# 查看leader
$ kubectl get endpoints kube-scheduler --namespace=kube-system -o yaml

8. 部署kubelet(worker节点)(难点、慎重)

8.1 预先下载需要的镜像

准备:预先导入pause镜像

$ docker load < pause.tar,此处不做赘述

8.2 创建bootstrap配置文件
bash 复制代码
注意:这里不用这种办法生成token,使用前面生成的token即可,忽略343-349行即可!!!!!!!!!!!!!
# 创建 token
$ export BOOTSTRAP_TOKEN=$(kubeadm token create \
      --description kubelet-bootstrap-token \
      --groups system:bootstrappers:worker \
      --kubeconfig kube.config)
注:提示kubeadm命令未找到???????????????????? 
解决方法:直接复制柱节点上pki目录到node节点  

# 设置集群参数  (修改kube.config   kubelet-bootstrap.kubeconfig)
$ cd target/pki/admin
$ kubectl config set-cluster kubernetes \
      --certificate-authority=../ca.pem \
      --embed-certs=true \
      --server=https://192.168.10.178:6443 \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 设置客户端认证参数
$ kubectl config set-credentials kubelet-bootstrap \
      --token=701822b658427a198f3ab76bf6a9edba \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 设置上下文参数
$ kubectl config set-context default \
      --cluster=kubernetes \
      --user=kubelet-bootstrap \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 设置默认上下文
$ kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig

# 把生成的配置copy到每个worker节点上
$ scp kubelet-bootstrap.kubeconfig <user>@<node-ip>:/etc/kubernetes/kubelet-bootstrap.kubeconfig

# 先在worker节点上创建目录(每个节点都要创建)
$ mkdir -p /etc/kubernetes/pki

# 把ca分发到每个worker节点  (下次尝试不覆盖)
$ scp target/pki/ca.pem <user>@<node-ip>:/etc/kubernetes/pki/
8.3 kubelet配置文件

把kubelet配置文件分发到每个worker节点上

bash 复制代码
注:复制文件直接从本地上传到node节点,并修改文件信息(这里是config.yaml文件)(services文件夹中)
$ scp target/worker-<node-ip>/kubelet.config.json <user>@<node-ip>:/etc/kubernetes/
8.4 kubelet服务文件 (修改kubelet.service,改镜像名字和版本)

把kubelet服务文件分发到每个worker节点上

bash 复制代码
$ scp target/worker-<node-ip>/kubelet.service <user>@<node-ip>:/etc/systemd/system/
8.5 启动服务

kublet 启动时查找配置的 --kubeletconfig 文件是否存在,如果不存在则使用 --bootstrap-kubeconfig 向 kube-apiserver 发送证书签名请求 (CSR)。

kube-apiserver 收到 CSR 请求后,对其中的 Token 进行认证(事先使用 kubeadm 创建的 token),认证通过后将请求的 user 设置为 system:bootstrap:,group 设置为 system:bootstrappers,这就是Bootstrap Token Auth。

bash 复制代码
# bootstrap附权
注意:
$ kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
$ kubectl create clusterrolebinding kubelet-bootstrap5 --clusterrole=system:node-bootstrapper --user=system:serviceaccount:kube-system:kubernetes-dashboard
  下面三条有问题,不要执行!!!!!!!
$ kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers
  kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:controller:node-controller --group=system:kube-controller-manager
  kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:controller:node-controller --user=system:kube-controller-manager
# 启动服务
$ mkdir -p /var/lib/kubelet
$ systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet

在允许get nodes之前应该先赋予kube-controller-manager 管理node的权限,所以,需要先执行下面这句:
kubectl create clusterrolebinding kubelet-bootstrap1 --clusterrole=cluster-admin --user=system:kube-controller-manager

# 在master上Approve bootstrap请求
$ kubectl get csr
$ kubectl certificate approve <name> 
以上三行处理请求可以用下面这句循环来替换:
for i in `kubectl get csr|awk '{print $1}'|grep -v "NAME"`;do kubectl certificate approve $i;done

检查处理结果:
kubectl get node
应该显示可以取到的node节点信息

------------------------------------------------
路由转发
vi /etc/sysctl.conf

net.ipv4.ip_forward=1


<cgropp> 问题,
 vi /etc/docker/daemon.json
	添加内容为 :
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries":["0.0.0.0/0"]
}
重启docker
systemctl restart docker
----------------------------------------------------




# 查看服务状态l
$ service kubelet status

# 查看日志
$ journalctl -f -u kubelet

9. 部署kube-proxy(worker节点)

9.1 创建证书和私钥 (修改kube-proxy.kubeconfig)
bash 复制代码
$ cd target/pki/proxy

$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy
9.2 创建和分发 kubeconfig 文件
bash 复制代码
# 创建kube-proxy.kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://192.168.10.:6443 \
  --kubeconfig=kube-proxy.kubeconfig
$ kubectl config set-credentials kube-proxy \
  --client-certificate=kube-proxy.pem \
  --client-key=kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig
$ kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig
$ kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

# 分发kube-proxy.kubeconfig
$ scp kube-proxy.kubeconfig <user>@<node-ip>:/etc/kubernetes/
9.3 分发kube-proxy.config
bash 复制代码
注:下面这行不用执行(2
-----------------------------------$ scp target/worker-<node-ip>/kube-proxy.config.yaml <user>@<node-ip>:/etc/kubernetes/--------------------
9.4 分发kube-proxy服务文件 (修改kube-proxy.service)
bash 复制代码
$ scp target/services/kube-proxy.service <user>@<node-ip>:/etc/systemd/system/
9.5 启动服务
bash 复制代码
# 创建依赖目录
$ mkdir -p /var/lib/kube-proxy && mkdir -p /var/log/kubernetes

# 启动服务
$ systemctl daemon-reload && systemctl enable kube-proxy && systemctl restart kube-proxy

# 查看状态
$ service kube-proxy status

# 查看日志
$ journalctl -f -u kube-proxy

10. 部署CNI插件 - calico (倒镜像)

我们使用calico官方的安装方式来部署。

bash 复制代码
# 创建目录(在配置了kubectl的节点上执行)
$ mkdir -p /etc/kubernetes/addons

# 上传calico配置到配置好kubectl的节点(一个节点即可)  (calico.yaml文件 )   不做修改
$ scp target/addons/calico* <user>@<node-ip>:/etc/kubernetes/addons/


修改calico.yaml 文件的網卡。  (772行)
查詢網卡: ip addr show  
(enp0s3)


# 部署calico
$ kubectl create -f /etc/kubernetes/addons/calico-rbac-kdd.yaml  //不执行
$ kubectl create -f /etc/kubernetes/addons/calico.yaml

如果出錯 刪除(kubectl delete -f /etc/kubernetes/addons/calico.yaml)

# 查看状态
$ kubectl get pods -n kube-system
kubectl get pod -A

11. 部署DNS插件 - coredns (在images 的calico目录下) (coredns.yaml不做修改)

bash 复制代码
# 上传配置文件
$ scp target/addons/coredns.yaml <user>@<node-ip>:/etc/kubernetes/addons/

# 部署coredns
$ kubectl create -f /etc/kubernetes/addons/coredns.yaml


## 12. 部署dashboard
修改yaml文件的镜像信息,
并绑定serviceaccount
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard
分发
scp target/addons/dashboard.yaml <user>@<node-ip>:/etc/kubernetes/addons/
創建
kubectl create -f /etc/kubernetes/addons/kubernetes-dashboard.yaml

## 13. 部署metrics-server
修改yaml文件镜像信息,
并绑定 涉及node权限问题
kubectl create clusterrolebinding system-node-role-bound --clusterrole=system:node --group=system:nodes

分发
scp target/addons/metrics.yaml <user>@<node-ip>:/etc/kubernetes/addons/

分发文件夹
cp -r metric-server /etc/kubernetes/addons/
創建
kubectl create -f /etc/kubernetes/addons/metrics.yaml

多个文件时,进入文件夹
kubectl create -f .


## 14. 其他监控组件正常部署即可,无影响
(1) Prometheus修改配置文件,提供修改模板
(2) node-exporter无影响
(3) state-metrics无影响

查看kubernetes Dashboard

访问地址:https://192.168.10.178:30090

问题:页面中没有数据,没有权限,需要赋权

1、更改iptables ,修改FORWARD的值为ACCEPT (一般情况就是ACCEPT,不用修改)

#查看iptables信息

iptables -nL

#修改iptables的forward值

iptables -P FORWARD ACCEPT

2、赋权

kubectl create clusterrolebinding kubelet-bootstrap-admin --clusterrole=cluster-admin --user=kubelet-bootstrap //赋权

如果没有高级设置 ,点击空白 输入 thisisunsafe

相关推荐
ggaofeng2 小时前
通过命令学习k8s
云原生·容器·kubernetes
death bell2 小时前
Docker基础概念
运维·docker·容器
想学习java初学者5 小时前
Docker Compose部署Kafka(非Zookeeper)
docker·容器·kafka
qq_道可道5 小时前
K8S升级到1.24后,切换运行时导致 dind 构建镜像慢根因定位与解决
云原生·容器·kubernetes
SONGW20186 小时前
k8s拓扑域 :topologyKey
kubernetes
weixin_438197387 小时前
K8S实现反向代理,负载均衡
linux·运维·服务器·nginx·kubernetes
郝同学的测开笔记8 小时前
云原生探索系列(十二):Go 语言接口详解
后端·云原生·go
mit6.8249 小时前
[Docker#5] 镜像仓库 | 命令 | 实验:搭建Nginx | 创建私有仓库
linux·后端·docker·云原生
牛右刀薛面9 小时前
麒麟V10,arm64,离线安装docker和docker-compose
运维·docker·容器·麒麟·鲲鹏
后端常规开发人员9 小时前
在 Mac 上使用 Docker 安装宝塔并部署 LNMP 环境
macos·docker·容器·宝塔