kubespray离线安装k8s
系统环境
OS:
Static hostname: test
Icon name: computer-vm
Chassis: vm
Machine ID: 22349ac6f9ba406293d0541bcba7c05d
Boot ID: 83bb7e5dbf27453c94ff9f1fe88d5f02
Virtualization: vmware
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-105-generic
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform
repo:
10.1.1.70
k8s_master:
10.1.1.71
kubespray version:
2.25.0
kubernetes version:
1.29.5
kubespray离线下载预配置
-
准备 kubespray 环境:
- 更新系统包列表:
apt update
- 安装 Git、Python3 和 pip:
apt install git python3 python3-pip -y
- 克隆 Kubespray 仓库:
git clone https://github.com/kubernetes-incubator/kubespray.git
- 进入 Kubespray 目录:
cd kubespray
- 更新系统包列表:
-
创建配置:
- 生成下载包和镜像列表:
apt install ansible -y && cd contrib/offline && bash generate_list.sh
- 生成下载包和镜像列表:
安装配置离线file repo
-
下载软件包到目录:
wget -x -P temp/files -i temp/files.list
-
启动简单的http服务器:
cd temp/files && python3 -m http.server 8000
安装配置harbor和离线镜像库
安装docker和docker-compose
apt install docker docker-compose -y
安装harbor
下载
wget https://github.com/goharbor/harbor/releases/download/v2.11.0-rc1/harbor-offline-installer-v2.11.0-rc1.tgz
tar xvf harbor-offline-installer-v2.11.0-rc1.tgz
生成私有证书
生成Harbor私有证书的证书和密钥通常涉及以下步骤:
-
创建一个文件夹:用于存放生成的证书和密钥。
mkdir -p /data/certs && cd /data/certs
-
生成CA证书:首先,创建CA的私钥和证书。
openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/CN=harbor.sys.foobar.com" -key ca.key -out ca.crt
将
harbor.sys.foobar.com
替换为您的Harbor域名。 -
生成服务器证书:创建服务器的私钥和证书签名请求(CSR)。
openssl genrsa -out server.key 4096 openssl req -new -sha512 -subj "/CN=harbor.sys.foobar.com" -key server.key -out server.csr
同样,将
harbor.sys.foobar.com
替换为您的Harbor域名。 -
创建v3.ext文件:为了生成服务器证书,需要一个v3.ext文件来定义证书的使用。
cat > v3.ext <<-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1=harbor.sys.foobar.com EOF
将
harbor.sys.foobar.com
替换为您的Harbor域名。 -
生成服务器证书:使用CA证书和私钥对CSR进行签名。
openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
-
配置Harbor:将生成的
server.crt
和server.key
文件复制到Harbor的配置目录中,并在harbor.yml
文件中指定证书和私钥的路径。
配置安装
配置harbor.yml.tpl
文件是Harbor安装和设置的关键步骤。这个文件包含了Harbor实例的所有配置信息。以下是配置harbor.yml.tpl
的基本步骤:
-
复制模板文件:首先,您需要将
harbor.yml.tpl
模板文件复制为harbor.yml
,这是Harbor将要使用的配置文件。cp harbor.yml.tmpl harbor.yml
-
编辑配置文件:使用文本编辑器打开
harbor.yml
文件进行编辑。vim harbor.yml
-
配置主要参数:在
harbor.yml
文件中,您需要配置以下主要参数:hostname
:设置Harbor服务器的主机名或IP地址(harbor.sys.foobar.com)。port
:设置HTTP和HTTPS的端口号,默认是80和443(默认)。harbor_admin_password
:设置Harbor管理员账户的初始密码(默认或修改)。certificate
和private_key
:如果启用HTTPS,指定SSL证书和私钥的路径(/root/harbor/server.crt, /root/harbor/server.key)。
-
保存并退出:完成配置后,保存文件并退出编辑器。
-
运行
prepare
脚本:在安装Harbor之前,运行prepare
脚本来准备环境。# 注意镜像拉取错误可能是版本问题,修要修改脚本中goharbor/prepare:v2.11.0为goharbor/prepare:v2.11.0-rc1 ./prepare
-
安装Harbor:运行
install.sh
脚本来安装Harbor。./install.sh
下载镜像
-
创建k8s项目:新建项目
-
下载依赖镜像
- 设置hosts解析,
10.1.1.70 harbor.sys.foobar.com
。 - 安装 skopeo,
apt install skopeo -y
,将依赖镜像同步到自建私有镜像仓库。 - 同步镜像:
for image in $(cat temp/images.list); do skopeo copy --dest-creds=admin:Harbor12345 --src-tls-verify=false --dest-tls-verify=false docker://${image} docker://harbor.sys.foobar.com/k8s/${image#*/}; done
,需要注意使用的域名和证书上的hostname以及harbor.yml中配置的hostname一致。
- 设置hosts解析,
master node配置kubespray
-
从repo服务器拷贝kubespray到本地
- 更新系统包列表:
apt update
- 安装 Git、Python3 和 pip:
apt install git python3 python3-pip -y
- 从repo服务器克隆 Kubespray 仓库,
git clone https://github.com/kubernetes-incubator/kubespray.git
- 进入 Kubespray 目录:
cd kubespray
- 安装所需依赖:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
- 验证 Ansible 版本:
ansible --version
- 复制样本清单:
cp -rfp inventory/sample inventory/mycluster
- 更新系统包列表:
-
配置集群参数:
下载的file list和image list会根据配置文件生成- 编辑
k8s_cluster.yml
文件以设置 Kubernetes 版本和网络插件等参数:vim inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
- 启用 Kubernetes 仪表板和入口控制器:
vim inventory/mycluster/group_vars/k8s_cluster/addons.yml
- 编辑
vim roles/kubespray-defaults/defaults/main/download.yml
,默认使用offline.yml中定义的地址。
- 编辑
-
配置kubespray
- 编辑
offline.yml
文件,替换file和image镜像地址:vim /root/kubespray/inventory/mycluster/group_vars/all/offline.yml
--- ## Global Offline settings ### Private Container Image Registry registry_host: "harbor.sys.foobar.com/k8s" files_repo: "http://10.1.1.70:8000" ### If using CentOS, RedHat, AlmaLinux or Fedora # yum_repo: "http://myinternalyumrepo" ### If using Debian # debian_repo: "http://myinternaldebianrepo" ### If using Ubuntu # ubuntu_repo: "http://myinternalubunturepo" ## Container Registry overrides kube_image_repo: "{{ registry_host }}" gcr_image_repo: "{{ registry_host }}" github_image_repo: "{{ registry_host }}" docker_image_repo: "{{ registry_host }}" quay_image_repo: "{{ registry_host }}" ## Kubernetes components kubeadm_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm" kubectl_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl" kubelet_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet" ## Two options - Override entire repository or override only a single binary. ## [Optional] 1 - Override entire binary repository # github_url: "https://my_github_proxy" # dl_k8s_io_url: "https://my_dl_k8s_io_proxy" # storage_googleapis_url: "https://my_storage_googleapi_proxy" # get_helm_url: "https://my_helm_sh_proxy" ## [Optional] 2 - Override a specific binary ## CNI Plugins cni_download_url: "{{ files_repo }}/github.com/containernetworking/plugins/releases/download/{{ cni_version }}/cni-plugins-linux-{{ image_arch }}-{{cni_version }}.tgz" ## cri-tools crictl_download_url: "{{ files_repo }}/github.com/kubernetes-sigs/cri-tools/releases/download/{{ crictl_version }}/crictl-{{ crictl_version }}-{{ansible_system | lower }}-{{ image_arch }}.tar.gz" ## [Optional] etcd: only if you use etcd_deployment=host etcd_download_url: "{{ files_repo }}/github.com/etcd-io/etcd/releases/download/{{ etcd_version }}/etcd-{{ etcd_version }}-linux-{{ image_arch }}.tar.gz" # [Optional] Calico: If using Calico network plugin calicoctl_download_url: "{{ files_repo }}/github.com/projectcalico/calico/releases/download/{{ calico_ctl_version }}/calicoctl-linux-{{ image_arch }}" # [Optional] Calico with kdd: If using Calico network plugin with kdd datastore calico_crds_download_url: "{{ files_repo }}/github.com/projectcalico/calico/archive/{{ calico_version }}.tar.gz" # [Optional] Cilium: If using Cilium network plugin ciliumcli_download_url: "{{ files_repo }}/github.com/cilium/cilium-cli/releases/download/{{ cilium_cli_version }}/cilium-linux-{{ image_arch }}.tar.gz" # [Optional] helm: only if you set helm_enabled: true helm_download_url: "{{ files_repo }}/get.helm.sh/helm-{{ helm_version }}-linux-{{ image_arch }}.tar.gz" # [Optional] crun: only if you set crun_enabled: true crun_download_url: "{{ files_repo }}/github.com/containers/crun/releases/download/{{ crun_version }}/crun-{{ crun_version }}-linux-{{ image_arch }}" # [Optional] kata: only if you set kata_containers_enabled: true kata_containers_download_url: "{{ files_repo }}/github.com/kata-containers/kata-containers/releases/download/{{ kata_containers_version }}kata-static-{{ kata_containers_version }}-{{ ansible_architecture }}.tar.xz" # [Optional] cri-dockerd: only if you set container_manager: docker cri_dockerd_download_url: "{{ files_repo }}/github.com/Mirantis/cri-dockerd/releases/download/v{{ cri_dockerd_version }}/cri-dockerd-{{cri_dockerd_version }}.{{ image_arch }}.tgz" # [Optional] runc: if you set container_manager to containerd or crio runc_download_url: "{{ files_repo }}/github.com/opencontainers/runc/releases/download/{{ runc_version }}/runc.{{ image_arch }}" # [Optional] cri-o: only if you set container_manager: crio # crio_download_base: "download.opensuse.org/repositories/devel:kubic:libcontainers:stable" # crio_download_crio: "http://{{ crio_download_base }}:/cri-o:/" crio_download_url: "{{ files_repo }}/storage.googleapis.com/cri-o/artifacts/cri-o.{{ image_arch }}.{{ crio_version }}.tar.gz" skopeo_download_url: "{{ files_repo }}/github.com/lework/skopeo-binary/releases/download/{{ skopeo_version }}/skopeo-linux-{{ image_arch }}" # [Optional] containerd: only if you set container_runtime: containerd containerd_download_url: "{{ files_repo }}/github.com/containerd/containerd/releases/download/v{{ containerd_version }}/containerd-{{containerd_version }}-linux-{{ image_arch }}.tar.gz" nerdctl_download_url: "{{ files_repo }}/github.com/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-{{ansible_system | lower }}-{{ image_arch }}.tar.gz" # [Optional] runsc,containerd-shim-runsc: only if you set gvisor_enabled: true gvisor_runsc_download_url: "{{ files_repo }}/storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/runsc" gvisor_containerd_shim_runsc_download_url: "{{ files_repo }}/storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ansible_architecture }}/containerd-shim-runsc-v1" # [Optional] Krew: only if you set krew_enabled: true krew_download_url: "{{ files_repo }}/github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew-{{ host_os }}_{{ image_arch }}.tar.gz" ## CentOS/Redhat/AlmaLinux ### For EL7, base and extras repo must be available, for EL8, baseos and appstream ### By default we enable those repo automatically # rhel_enable_repos: false ### Docker / Containerd # docker_rh_repo_base_url: "{{ yum_repo }}/docker-ce/$releasever/$basearch" # docker_rh_repo_gpgkey: "{{ yum_repo }}/docker-ce/gpg" ## Fedora ### Docker # docker_fedora_repo_base_url: "{{ yum_repo }}/docker-ce/{{ ansible_distribution_major_version }}/{{ ansible_architecture }}" # docker_fedora_repo_gpgkey: "{{ yum_repo }}/docker-ce/gpg" ### Containerd # containerd_fedora_repo_base_url: "{{ yum_repo }}/containerd" # containerd_fedora_repo_gpgkey: "{{ yum_repo }}/docker-ce/gpg" ## Debian ### Docker # docker_debian_repo_base_url: "{{ debian_repo }}/docker-ce" # docker_debian_repo_gpgkey: "{{ debian_repo }}/docker-ce/gpg" ### Containerd # containerd_debian_repo_base_url: "{{ debian_repo }}/containerd" # containerd_debian_repo_gpgkey: "{{ debian_repo }}/containerd/gpg" # containerd_debian_repo_repokey: 'YOURREPOKEY' ## Ubuntu ### Docker # docker_ubuntu_repo_base_url: "{{ ubuntu_repo }}/docker-ce" # docker_ubuntu_repo_gpgkey: "{{ ubuntu_repo }}/docker-ce/gpg" ### Containerd # containerd_ubuntu_repo_base_url: "{{ ubuntu_repo }}/containerd" # containerd_ubuntu_repo_gpgkey: "{{ ubuntu_repo }}/containerd/gpg" # containerd_ubuntu_repo_repokey: 'YOURREPOKEY'
- 配置hosts文件
echo '10.1.1.70 harbor.sys.foobar.com' >>/etc/hosts
- 编辑
-
创建和配置主机清单:
-
声明 IP 地址数组并创建主机清单文件:
# 当前只使用一个主节点 declare -a IPS=(10.1.1.71) CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
-
修改清单文件以设置控制节点和工作节点:
vim inventory/mycluster/hosts.yaml
-
-
部署 Kubernetes 集群:
-
将 SSH 密钥从 Ansible 节点复制到所有其他节点:
ssh-copy-id user@node_ip
-
禁用防火墙并启用 IPv4 转发:
ansible all -i inventory/mycluster/hosts.yaml -m shell -a "sudo systemctl stop firewalld && sudo systemctl disable firewalld" ansible all -i inventory/mycluster/hosts.yaml -m shell -a "echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf"
-
-
拉取harbor镜像ssl报错时containerd证书配置
crictl拉取镜像配置证书- k8s各个节点创建目录,
mkdir -p /etc/containerd/certs
- 从harbor节点拷贝证书,
scp /root/harbor/server.crt node:/etc/containerd/certs/server.crt
- 修改kubespray配置文件,相当于修改各个k8s节点containerd配置文件并重启,
vim roles/container-engine/containerd/templates/config.toml.j2
version = 2 root = "{{ containerd_storage_dir }}" state = "{{ containerd_state_dir }}" oom_score = {{ containerd_oom_score }} {% if containerd_extra_args is defined %} {{ containerd_extra_args }} {% endif %} [grpc] max_recv_message_size = {{ containerd_grpc_max_recv_message_size }} max_send_message_size = {{ containerd_grpc_max_send_message_size }} [debug] level = "{{ containerd_debug_level }}" [metrics] address = "{{ containerd_metrics_address }}" grpc_histogram = {{ containerd_metrics_grpc_histogram | lower }} [plugins] [plugins."io.containerd.grpc.v1.cri"] sandbox_image = "{{ pod_infra_image_repo }}:{{ pod_infra_image_tag }}" max_container_log_line_size = {{ containerd_max_container_log_line_size }} enable_unprivileged_ports = {{ containerd_enable_unprivileged_ports | lower }} enable_unprivileged_icmp = {{ containerd_enable_unprivileged_icmp | lower }} {% if enable_cdi %} enable_cdi = true cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"] {% endif %} [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "{{ containerd_default_runtime }}" snapshotter = "{{ containerd_snapshotter }}" discard_unpacked_layers = {{ containerd_discard_unpacked_layers | lower }} [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] {% for runtime in [containerd_runc_runtime] + containerd_additional_runtimes %} [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.{{ runtime.name }}] runtime_type = "{{ runtime.type }}" runtime_engine = "{{ runtime.engine }}" runtime_root = "{{ runtime.root }}" {% if runtime.base_runtime_spec is defined %} base_runtime_spec = "{{ containerd_cfg_dir }}/{{ runtime.base_runtime_spec }}" {% endif %} [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.{{ runtime.name }}.options] {% for key, value in runtime.options.items() %} {% if value | string != "true" and value | string != "false" %} {{ key }} = "{{ value }}" {% else %} {{ key }} = {{ value }} {% endif %} {% endfor %} {% endfor %} {% if kata_containers_enabled %} [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-qemu] runtime_type = "io.containerd.kata-qemu.v2" {% endif %} {% if gvisor_enabled %} [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc] runtime_type = "io.containerd.runsc.v1" {% endif %} [plugins."io.containerd.grpc.v1.cri".registry] # 以下行为添加内容 [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.sys.foobar.com".tls] ca_file = "/etc/containerd/certs/server.crt" # 或者如下配置 # insecure_skip_verify = true # harbor镜像拉取认证信息 [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.sys.foobar.com".auth] username = "admin" password = "Harbor12345" {% if containerd_use_config_path is defined and containerd_use_config_path|bool %} config_path = "{{ containerd_cfg_dir }}/certs.d" {% else %} [plugins."io.containerd.grpc.v1.cri".registry.mirrors] {% set insecure_registries_addr = [] %} {% for registry in containerd_registries_mirrors %} [plugins."io.containerd.grpc.v1.cri".registry.mirrors."{{ registry.prefix }}"] {% set endpoint = [] %} {% for mirror in registry.mirrors %} {% if endpoint.append(mirror.host) %}{% endif %} {% if mirror.skip_verify is defined and mirror.skip_verify|bool %}{% if insecure_registries_addr.append(mirror.host | urlsplit('netloc')) %}{% endif %}{% endif %} {% endfor %} endpoint = ["{{ ( endpoint | unique ) | join('","') }}"] {% endfor %} {% for addr in insecure_registries_addr | unique %} [plugins."io.containerd.grpc.v1.cri".registry.configs."{{ addr }}".tls] insecure_skip_verify = true {% endfor %} {% endif %} {% for registry in containerd_registry_auth if registry['registry'] is defined %} {% if (registry['username'] is defined and registry['password'] is defined) or registry['auth'] is defined %} [plugins."io.containerd.grpc.v1.cri".registry.configs."{{ registry['registry'] }}".auth] {% if registry['username'] is defined and registry['password'] is defined %} password = "{{ registry['password'] }}" username = "{{ registry['username'] }}" {% else %} auth = "{{ registry['auth'] }}" {% endif %} {% endif %} {% endfor %} {% if nri_enabled and containerd_version is version('1.7.0', '>=') %} [plugins."io.containerd.nri.v1.nri"] disable = false {% endif %} {% if containerd_tracing_enabled %} [plugins."io.containerd.tracing.processor.v1.otlp"] endpoint = "{{ containerd_tracing_endpoint }}" protocol = "{{ containerd_tracing_protocol }}" {% if containerd_tracing_protocol == "grpc" %} insecure = false {% endif %} [plugins."io.containerd.internal.v1.tracing"] sampling_ratio = {{ containerd_tracing_sampling_ratio }} service_name = "{{ containerd_tracing_service_name }}" {% endif %}
相当于修改containerd配置文件,不过kubespray每次运行会覆盖,所以需要修改kubespray配置
vim /etc/containerd/config.toml
version = 2 root = "/var/lib/containerd" state = "/run/containerd" oom_score = 0 [grpc] max_recv_message_size = 16777216 max_send_message_size = 16777216 [debug] level = "info" [metrics] address = "" grpc_histogram = false [plugins] [plugins."io.containerd.grpc.v1.cri"] sandbox_image = "harbor.sys.foobar.com/pause:3.9" max_container_log_line_size = -1 enable_unprivileged_ports = false enable_unprivileged_icmp = false [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" snapshotter = "overlayfs" discard_unpacked_layers = true [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" runtime_engine = "" runtime_root = "" base_runtime_spec = "/etc/containerd/cri-base.json" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] systemdCgroup = true binaryName = "/usr/local/bin/runc" [plugins."io.containerd.grpc.v1.cri".registry] # 以下两行为添加内容 [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.sys.foobar.com".tls] ca_file = "/etc/containerd/certs/server.crt" [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://registry-1.docker.io"]
重启containerd,
systemctl restart containerd
ctr拉取镜像配置证书,注意kubespray部署k8s镜像使用ctr命令,例如
/usr/local/bin/ctr -n k8s.io images pull --hosts-dir /etc/containerd/certs.d harbor.sys.foobar.com/k8s/calico/pod2daemon-flexvol:v3.27.3
mkdir -p /etc/containerd/certs.d/harbor.sys.foobar.com cat >/etc/containerd/certs.d/harbor.sys.foobar.com/hosts.toml<<EOF server = "https://harbor.sys.foobar.com" [host."https://harbor.sys.foobar.com"] capabilities = ["pull","resolve"] skip_verify = true override_path = false EOF
- k8s各个节点创建目录,
-
kubespray报错E0527 19:22:56.946830 35606 remote_image.go:180] “PullImage from image service failed” err=“rpc error: code = Unknown desc = failed to pull and unpack image “harbor.sys.foobar.com/k8s/calico/node:v3.27.3”: failed to resolve reference “harbor.sys.foobar.com/k8s/calico/node:v3.27.3”: pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials” image=“harbor.sys.foobar.com/k8s/calico/node:v3.27.3”
FATA[0000] pulling image: failed to pull and unpack image “harbor.sys.foobar.com/k8s/calico/node:v3.27.3”: failed to resolve reference “harbor.sys.foobar.com/k8s/calico/node:v3.27.3”: pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials- 将harbor仓库设为公开
- 或者
vim roles/kubespray-defaults/defaults/main/download.yml
修改,添加--user {{ harbor_auth }}
nerdctl_image_pull_command: "{{ bin_dir }}/ctr -n k8s.io images pull{% if containerd_registries_mirrors is defined %} --user {{ harbor_auth }} --hosts-dir {{ containerd_cfg_dir }}/certs.d{%- endif -%}"
vim roles/container-engine/containerd/defaults/main.yml
添加harbor_auth: admin:Harbor12345
-
启动kubespray部署
- 启动 Kubernetes 部署:
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml
- 启动 Kubernetes 部署:
FAQ
如何在k8s上安装kubesphere
准备工作
- 您的 Kubernetes 版本必须为:v1.20.x、v1.21.x、v1.22.x、v1.23.x、* v1.24.x、* v1.25.x 和 * v1.26.x。带星号的版本可能出现边缘节点部分功能不可用的情况。因此,如需使用边缘节点,推荐安装 v1.23.x。
- 确保您的机器满足最低硬件要求:CPU > 1 核,内存 > 2 GB。
- 在安装之前,需要配置 Kubernetes 集群中的默认存储类型。
备注
- 当使用
--cluster-signing-cert-file
和--cluster-signing-key-file
参数启动时,在kube-apiserver
中会激活 CSR 签名功能。请参见 RKE 安装问题。 - 有关在 Kubernetes 上安装 KubeSphere 的准备工作,请参见准备工作。
部署 KubeSphere
确保您的机器满足安装的前提条件之后,可以按照以下步骤安装 KubeSphere。
-
执行以下命令开始安装:
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/kubesphere-installer.yaml kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/cluster-configuration.yaml
-
检查安装日志:
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name') -f
-
使用
kubectl get pod --all-namespaces
查看所有 Pod 是否在 KubeSphere 的相关命名空间中正常运行。如果是,请通过以下命令检查控制台的端口(默认为30880
):kubectl get svc/ks-console -n kubesphere-system
-
确保在安全组中打开了端口
30880
,并通过 NodePort(IP:30880)
使用默认帐户和密码(admin/P@88w0rd)
访问 Web 控制台。 -
登录控制台后,您可以在系统组件中检查不同组件的状态。如果要使用相关服务,可能需要等待某些组件启动并运行。
kubespray如何部署kubernetes dashboard
在使用 Kubespray 部署 Kubernetes 集群之后,你可以通过以下步骤来部署 Kubernetes Dashboard:
-
确认是否启用安装:
- 检查
kubespray/inventory/k8s/group_vars/k8s-cluster/addons.yml
文件中的dashboard_enabled
设置是否为true
。 - 确认是否已成功安装 Kubernetes Dashboard。
- 检查
-
修改 Kubernetes Dashboard Service 配置:
-
使用以下命令编辑 Kubernetes Dashboard 的 Service 配置:
kubectl -n kube-system edit service kubernetes-dashboard
-
将 Service 的类型从
ClusterIP
改为NodePort
。 -
保存并退出编辑。
-
-
查看 Kubernetes Dashboard 端口:
-
执行命令查看Kubernetes Dashboard端口:
kubectl get service -A -o wide | grep kubernetes-dashboard
-
访问https://kubesdashboardip:port
-
-
设置 Kubernetes Dashboard 登录信息:
-
在登录页面上,你可以使用
kubeconfig
或token
进行身份验证。 -
以下是使用
token
登录的示例:-
创建 serviceaccount。
kubectl create serviceaccount dashboard-admin -n kube-system
-
创建 secret:
kubectl create secret generic dashboard-admin --from-literal=token=k8sdashboard123 -n kube-system
-
绑定 serviceaccount
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
-
获取
admin-token
的 secret 名称:kubectl -n kube-system get secret | grep dashboard-admin
-
获取 token:
kubectl -n kube-system get secret admin-token-h2dxb -o jsonpath={.data.token} | base64 -d
-
-
成功登录后,你就可以使用 Kubernetes Dashboard 进行集群管理了。
-
总之,通过 Kubespray 安装 Kubernetes Dashboard 非常简单,只要 Kubernetes 安装成功,Dashboard 就会部署成功。
kubespray如何安装不同的k8s版本
Kubespray 是一个自由开源的工具,它提供了 Ansible 剧本 (playbook) 来部署和管理 Kubernetes 集群。它旨在简化跨多个节点的 Kubernetes 集群的安装过程,允许用户快速轻松地部署和管理生产就绪的 Kubernetes 集群。Kubespray 支持一系列操作系统,包括 Ubuntu、CentOS、Rocky Linux 和 Red Hat Enterprise Linux(RHEL),并可以在各种平台上部署 Kubernetes,包括裸机、公共云和私有云.
如果你想安装不同版本的 Kubernetes,你可以按照以下步骤进行操作:
-
修改配置文件:进入 Kubespray 目录后,我们需要修改
inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
配置文件,指定需要使用的 Kubernetes 版本。在该文件中,你可以找到以下配置项:kube_version
: 设置所需的 Kubernetes 版本。例如,如果你想使用 Kubernetes v1.18.0,可以将其设置为v1.18.0
。
-
运行部署命令:运行以下命令来执行部署:
ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml -b
这将使用你在配置文件中指定的 Kubernetes 版本来部署集群。
-
获取 kubeconfig:部署完成后,从 Master 节点上的
/root/.kube/config
路径获取到 kubeconfig 文件。你可以修改其中的 server 地址,将https://127.0.0.1:6443
改为非 Master 节点可以访问的地址,例如直接替换成其中一台 Master 节点的 IP 地址。
kubespray的每个版本只支持部署特定的k8s版本吗
Kubespray 的版本与支持的 Kubernetes (K8s) 版本之间有一定的关联。不同版本的 Kubespray 默认支持不同的 K8s 版本。以下是一些关键信息:
-
Kubespray 版本和默认支持的 K8s 版本:
- Kubespray 2.12 默认支持的最低 K8s 版本是 v1.15.0,最高支持的 K8s 版本是 v1.17.0。
- 具体的 Kubernetes 二进制文件版本如下:
- kubelet: v1.15.0
- kube-apiserver, kube-scheduler, kube-controller-manager: v1.15.0
- kubectl: v1.15.0
- 如果你使用的是 Kubespray 2.12,你可以部署 K8s 版本在 v1.15.0 到 v1.17.0 之间。
-
Kubespray 升级 K8s:
- Kubespray 使用 kubeadm 进行 K8s 的升级。目前,kubeadm 只支持跨越一个版本的升级,例如从 v1.13 升级到 v1.14,或从 v1.14 升级到 v1.15。
- 可以升级的组件包括:
- Docker
- Etcd
- kubelet 和 kube-proxy
- 网络插件(如 Calico 或 Flannel)
- kube-apiserver, kube-scheduler, and kube-controller-manager
- 插件(如 KubeDNS)
总之,Kubespray 和 K8s 版本之间的关系是密切的,你需要根据你的需求选择合适的 Kubespray 版本来部署对应的 K8s 版本。
目前k8s依然迭代较快,没有LTS版本吗
截至目前,Kubernetes (K8s) 并没有官方的长期支持(LTS)版本。但是,从 Kubernetes 1.19 版本开始,每个次要版本都会获得大约 1年的补丁支持¹。这意味着,尽管没有正式的 LTS 版本,但是每个次要版本都会在一定时间内继续接收更新和安全修复,为用户提供了一定程度的稳定性。
Kubernetes 的版本号遵循语义版本控制,表示为 x.y.z
,其中 x
是主要版本,y
是次要版本,z
是补丁版本。Kubernetes 项目维护最近三个次要版本的发布分支。例如,目前维护的版本包括 1.30、1.29 和 1.28¹。
此外,社区驱动的项目如 KLTS.io 提供对旧版本 Kubernetes 的额外支持,这可能对需要长期稳定环境的用户有帮助³。
因此,虽然没有官方的 LTS 版本,但 Kubernetes 的支持策略和社区的额外支持,为用户提供了足够的稳定性和安全性。
kubespray升级K8s会造成服务中断吗
使用 Kubespray 升级 Kubernetes (K8s) 集群时,是否会造成服务中断,主要取决于升级过程的管理和集群的配置。以下是一些关键点:
-
滚动升级:Kubespray 通常采用滚动升级的策略来更新集群节点。这意味着它会逐个升级节点,而不是同时升级所有节点。这样做的目的是为了最小化服务中断的可能性。
-
高可用性配置:如果你的 K8s 集群配置了高可用性,那么在升级过程中,即使某些节点暂时下线,服务也应该能够继续运行。
-
升级策略:在升级之前,应该制定详细的升级计划,并在非高峰时段进行升级,以减少对业务的影响。
-
测试升级:在生产环境中执行升级之前,在测试环境中进行彻底的升级测试是非常重要的,以确保升级过程不会影响服务的连续性。
-
备份和恢复计划:确保在升级前有完整的数据备份和恢复计划,以防升级过程中出现问题。
根据网络上的一些资源,虽然 Kubespray 设计了升级过程以尽量减少服务中断,但不能保证在升级过程中完全没有中断。因此,最佳实践是假设会有短暂的服务中断,并相应地进行计划。
总之,虽然 Kubespray 的设计目标是在不中断服务的情况下升级 K8s 集群,但在实际操作中,仍然需要谨慎规划和准备,以确保服务的平稳运行。
k8s集群网络插件比较
在 Kubernetes 中,选择适合的网络插件对于集群的性能、可靠性和管理效率至关重要。让我们比较一下目前最流行的几个 Kubernetes 网络插件:Flannel、Calico、Weave 和 Canal。
Flannel
- Flannel 是由 CoreOS 开发的项目,可能是最直接且最受欢迎的 CNI 插件之一。
- 它旨在实现更好的容器间和主机间网络连接。
- Flannel 相对容易安装和配置,被打包为单个二进制文件
flanneld
。 - 可以使用 Kubernetes 集群的现有 etcd 集群来存储其状态信息,无需专用的数据存储。
- 配置第三层 IPv4 overlay 网络,创建一个大型内部网络跨越集群中的每个节点。
- 使用 Docker 桥接接口为每个新容器分配地址,不同主机上的 Pod 通过 Flannel 将流量封装在 UDP 数据包中路由到适当的目标。
- 推荐使用 VXLAN 后端,因为性能更好且需要的手动干预较少。
Calico
- Calico 是出色的网络管理插件,具备复杂网络配置能力。
- 提供强大的网络功能,支持网络策略、路由和安全性。
- 使用 BGP 协议来管理边缘路由器之间的数据包路由。
- 配置灵活,但相对复杂,适合需要高级网络功能的场景。
- Calico 可以满足复杂网络需求,但需要更多的配置和管理。
Weave
- Weave 是另一个流行的 CNI 插件,提供 Overlay 网络和网络策略。
- 使用 VXLAN 或者 UDP 封装来创建 Overlay 网络。
- 支持网络隔离、路由和安全性。
- Weave 在易用性和功能之间取得了平衡,适合中等复杂度的网络需求。
总结:
- 对于小而简单的集群,可以使用 Flannel。
- 如果未来网络需要更多设备和复杂策略,Calico 是更好的选择。
- Weave 则适合中等复杂度的网络需求。
- 根据实际需求选择最适合自己集群的网络插件。🚀
terway是什么插件,为什么阿里云ack不用calico
Terway 是阿里云开源的基于专有网络 VPC 的容器网络接口(CNI)插件,支持基于 Kubernetes 标准的网络策略来定义容器间的访问策略。它将原生的弹性网卡分配给 Pod 实现 Pod 网络,支持高性能、高可扩展性和安全性的容器通信。
Calico 是另一个强大的开源容器网络和网络安全解决方案,广泛应用于 Kubernetes 集群和其他容器编排平台。它使用 BGP 协议来实现容器间的路由,支持灵活的网络策略和安全规则,适用于大规模部署。
为什么阿里云 ACK 不使用 Calico 呢?主要原因如下:
- Terway 是阿里云自研的网络插件,专门为 ACK 优化,支持高性能、高可扩展性和安全性的容器网络。
- Calico 在某些场景下可能较复杂,而 Terway 提供了更灵活的 IPAM 策略,避免了地址浪费。
- Terway 支持网络策略,可以实现容器间的隔离和安全通信,同时支持对单个容器做带宽的限流。
总之,根据实际需求选择最适合自己集群的网络插件即可。🚀
容器的缺点是什么
容器技术,尽管在开发和运维领域带来了许多优势,但也存在一些缺点。以下是容器技术的一些常见缺点:
-
构建和部署的挑战:
尽管容器化可以简化部署过程,但对于某些应用来说,容器化并不总是最佳选择。例如,传统的构建和部署工具如Jenkins,提供了成熟的功能和高度的定制化能力,而容器平台可能需要额外的工作来达到相同的自动化程度。 -
自动扩容和缩容的限制:
虽然容器支持无状态服务的自动扩容和缩容,但对于需要固定IP或有状态的服务来说,这可能不是理想的解决方案。此外,对于中小型企业来说,自动扩缩容的需求可能并不频繁。 -
隔离性较差:
相比基于hypervisor的虚拟机,容器的隔离性较差。虚拟机提供了更完善的隔离特性,因为它们的系统硬件资源是完全虚拟的,由hypervisor分配,这意味着bug、病毒或入侵可能影响一台虚拟机,但不会蔓延到其他虚拟机上。 -
安全性问题:
由于容器共享宿主机的内核,因此如果宿主机的内核存在漏洞,则所有容器都可能受到影响。这与虚拟机不同,后者为每个实例提供了独立的内核。 -
工具和生态系统的成熟度:
容器技术相对较新,其监控和管理工具的种类和成熟度仍在发展中。这可能导致在某些情况下,开发者需要花费额外的时间来解决问题。 -
数据持久化和存储问题:
容器天生适合无状态应用,但对于需要持久存储的应用,如数据库,容器可能不是最佳选择。数据持久化通常需要额外的存储解决方案和配置。 -
网络配置复杂性:
容器可能需要复杂的网络配置来确保通信和服务发现。这可能包括对网络策略、负载均衡和服务网格的配置,这些都可能增加系统的复杂性。 -
资源利用率的误解:
虽然容器可以提高资源利用率,但这并不意味着它们总是比虚拟机更节省资源。资源利用率取决于多种因素,包括应用的性质和部署的规模。 -
操作系统的选择:
容器通常使用最小化操作系统,这可能限制了某些应用的运行,特别是那些需要完整操作系统功能的应用。 -
应用兼容性:
并非所有应用都适合容器化。一些复杂的或者紧密耦合的应用可能难以拆分为容器化服务。
这些缺点并不意味着容器技术不值得使用,而是在考虑采用容器技术时,需要权衡这些因素以确定是否适合您的特定用例和环境。