离线二进制部署k8s 1.20
##可选保持时间同步 yum -y install ntpdate crontab -e #时间同步 */5 * * * * /usr/sbin/ntpdate 0.asia.pool.ntp.org ##关闭防火墙和selinux systemctl stop firewalld vim /etc/hosts 172.22.154.215 master215 172.22.154.216 node216 172.22.154.217 node217 ssh-keygen ssh-copy-id -i /root/.ssh/id_rsa.pub master215 ssh-copy-id -i /root/.ssh/id_rsa.pub node216 ssh-copy-id -i /root/.ssh/id_rsa.pub node217 软件准备 docker-20.10.7.tgz etcd-v3.4.15-linux-amd64.tar.gz kubernetes-server-linux-amd64.tar.gz cfssl cfssl-certinfo cfssljson 镜像准备 registry:2 calico/kube-controllers:v3.22.1 calico/cni:v3.22.1 calico/pod2daemon-flexvol:v3.22.1 calico/node:v3.22.1 registry.cn-beijing.aliyuncs.com/acs/aliyun-ingress-controller:v0.30.0.2-9597b3685-aliyun registry.cn-beijing.aliyuncs.com/acs/busybox:v1.29.2 mirrorgooglecontainers/pause-amd64:3.1 ## 创建目录结构 mkdir -pv /opt/etcd/{bin,cfg,ssl,logs} mkdir -pv /opt/k8s/{bin,cfg,ssl,logs,yaml} mkdir -pv /opt/cni/{bin,cfg,yaml} mkdir -pv /etc/cni/ etcd安装 添加证书生成工具 chmod +x cfssl cfssljson cfssl-certinfo cp cfssl cfssljson cfssl-certinfo /usr/bin/ #创建证书生成目录 mkdir -pv /data/TLS/{etcd,k8s} cd /data/TLS/etcd cd /data/TLS/etcd/ cat > ca-config.json << EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "www": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF cat > ca-csr.json << EOF { "CN": "etcd CA", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF 生成证书 cfssl gencert -initca ca-csr.json | cfssljson -bare ca #查看 ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem #hosts文件中包含etcd节点的IP可以多预留几个 cat > server-csr.json << EOF { "CN": "etcd", "hosts": [ "172.22.154.215", "172.22.154.216", "172.22.154.217", "172.22.154.218", "172.22.154.219" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } EOF #生成证书 cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem server-csr.json serverlsca-config.json.csr serverlsca-config.json-key.pem serverlsca-config.json.pem #拷贝证书 cp /data/TLS/etcd/*.pem /opt/etcd/ssl/ rsync -av /data/TLS/etcd/*.pem node216:/opt/etcd/ssl/ rsync -av /data/TLS/etcd/*.pem node217:/opt/etcd/ssl/ #拷贝软件 tar -zxvf etcd-v3.4.15-linux-amd64.tar.gz cp etcd-v3.4.15-linux-amd64/etcd* /opt/etcd/bin/ rsync -av /opt/etcd/bin/* node216:/opt/etcd/bin/ rsync -av /opt/etcd/bin/* node217:/opt/etcd/bin/ #配置etcd配置文件 #master215 cat > /opt/etcd/cfg/etcd.conf << EOF #[Member] ETCD_NAME="etcd-1" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.22.154.215:2380" ETCD_LISTEN_CLIENT_URLS="https://172.22.154.215:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.154.215:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.22.154.215:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.22.154.215:2380,etcd-2=https://172.22.154.216:2380,etcd-3=https://172.22.154.217:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" EOF #node216 cat > /opt/etcd/cfg/etcd.conf << EOF #[Member] ETCD_NAME="etcd-2" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.22.154.216:2380" ETCD_LISTEN_CLIENT_URLS="https://172.22.154.216:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.154.216:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.22.154.216:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.22.154.215:2380,etcd-2=https://172.22.154.216:2380,etcd-3=https://172.22.154.217:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" EOF #node217 cat > /opt/etcd/cfg/etcd.conf << EOF #[Member] ETCD_NAME="etcd-3" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.22.154.217:2380" ETCD_LISTEN_CLIENT_URLS="https://172.22.154.217:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.154.217:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.22.154.217:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.22.154.215:2380,etcd-2=https://172.22.154.216:2380,etcd-3=https://172.22.154.217:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" EOF # ETCD_NAME:节点名称,集群中唯一 # ETCD_DATA_DIR:数据目录 # ETCD_LISTEN_PEER_URLS:集群通信监听地址 # ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址 # ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址 # ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址 # ETCD_INITIAL_CLUSTER:集群节点地址 # ETCD_INITIAL_CLUSTER_TOKEN:集群Token # ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群 ###配置etcd启动文件 cat > /usr/lib/systemd/system/etcd.service << EOF [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify EnvironmentFile=/opt/etcd/cfg/etcd.conf ExecStart=/opt/etcd/bin/etcd \ --cert-file=/opt/etcd/ssl/server.pem \ --key-file=/opt/etcd/ssl/server-key.pem \ --peer-cert-file=/opt/etcd/ssl/server.pem \ --peer-key-file=/opt/etcd/ssl/server-key.pem \ --trusted-ca-file=/opt/etcd/ssl/ca.pem \ --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \ --logger=zap Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 启动etcd systemctl daemon-reload systemctl restart etcd systemctl enable etcd systemctl status etcd 安装DOCKER tar -zxvf docker-20.10.7.tgz cp docker/* /usr/bin/ scp docker/* node216:/usr/bin/ scp docker/* node217:/usr/bin/ ##三台操作 mkdir /etc/docker cat > /etc/docker/daemon.json << EOF { "data-root": "/var/lib/docker", "exec-opts": ["native.cgroupdriver=cgroupfs"], "insecure-registries": ["https://gsm39obv.mirror.aliyuncs.com","harbor.local"], "max-concurrent-downloads": 10, "live-restore": true, "log-driver": "json-file", "log-level": "warn", "log-opts": { "max-size": "50m", "max-file": "1" }, "storage-driver": "overlay2" } EOF ###harbor.local为后期要使用的本地镜像仓库地址 ##创建启动文件 cat > /usr/lib/systemd/system/docker.service << EOF [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.io [Service] Environment="PATH=/bin:/sbin:/usr/bin:/usr/sbin" ExecStart=/usr/bin/dockerd ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT ExecReload=/bin/kill -s HUP $MAINPID Restart=always RestartSec=5 LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target EOF ##启动docker systemctl daemon-reload systemctl restart docker systemctl status docker systemctl enable docker 安装MASTER tar -zxvf kubernetes-server-linux-amd64.tar.gz cd kubernetes/server/bin/ cp kubectl /usr/bin/ rsync -av kubectl kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy /opt/k8s/bin/ #同步到node节点 rsync -av kubelet kube-proxy node216:/opt/k8s/bin/ rsync -av kubelet kube-proxy node217:/opt/k8s/bin/ ##生成K8S证书 cd /data/TLS/k8s/ cd /data/TLS/k8s/ cat > ca-config.json << EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF cat > ca-csr.json << EOF { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing", "O": "k8s", "OU": "System" } ] } EOF cfssl gencert -initca ca-csr.json | cfssljson -bare ca ## 创建证书申请文件: ###可以多预留几个IP后期新增K8S节点 cat > server-csr.json << EOF { "CN": "kubernetes", "hosts": [ "10.0.0.1", "127.0.0.1", "172.22.154.215", "172.22.154.216", "172.22.154.217", "172.22.154.218", "172.22.154.219", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server # master 节点 #部署kube-apiserver cp /data/TLS/k8s/ca*pem /opt/k8s/ssl/ cp /data/TLS/k8s/server*pem /opt/k8s/ssl/ #同步到node节点 scp /data/TLS/k8s/ca.pem node216:/opt/k8s/ssl scp /data/TLS/k8s/ca.pem node217:/opt/k8s/ssl #创建配置文件 cat > /opt/k8s/cfg/kube-apiserver.conf << EOF KUBE_APISERVER_OPTS="--logtostderr=false \\ --feature-gates=RemoveSelfLink=false \\ --v=2 \\ --log-dir=/opt/k8s/logs \\ --etcd-servers=https://172.22.154.215:2379,https://172.22.154.216:2379,https://172.22.154.217:2379 \\ --bind-address=172.22.154.215 \\ --secure-port=6443 \\ --advertise-address=172.22.154.215 \\ --allow-privileged=true \\ --service-cluster-ip-range=10.0.0.0/24 \\ --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\ --authorization-mode=RBAC,Node \\ --enable-bootstrap-token-auth=true \\ --token-auth-file=/opt/k8s/cfg/token.csv \\ --service-node-port-range=30000-32767 \\ --kubelet-client-certificate=/opt/k8s/ssl/server.pem \\ --kubelet-client-key=/opt/k8s/ssl/server-key.pem \\ --tls-cert-file=/opt/k8s/ssl/server.pem \\ --tls-private-key-file=/opt/k8s/ssl/server-key.pem \\ --client-ca-file=/opt/k8s/ssl/ca.pem \\ --service-account-key-file=/opt/k8s/ssl/ca-key.pem \\ --service-account-issuer=https://kubernetes.default.svc.cluster.local \\ --service-account-signing-key-file=/opt/k8s/ssl/server-key.pem \\ --etcd-cafile=/opt/etcd/ssl/ca.pem \\ --etcd-certfile=/opt/etcd/ssl/server.pem \\ --etcd-keyfile=/opt/etcd/ssl/server-key.pem \\ --requestheader-client-ca-file=/opt/k8s/ssl/ca.pem \\ --proxy-client-cert-file=/opt/k8s/ssl/server.pem \\ --proxy-client-key-file=/opt/k8s/ssl/server-key.pem \\ --requestheader-allowed-names=kubernetes \\ --requestheader-extra-headers-prefix=X-Remote-Extra- \\ --requestheader-group-headers=X-Remote-Group \\ --requestheader-username-headers=X-Remote-User \\ --enable-aggregator-routing=true \\ --audit-log-maxage=30 \\ --audit-log-maxbackup=3 \\ --audit-log-maxsize=100 \\ --audit-log-path=/opt/k8s/logs/k8s-audit.log" EOF #创建TLS所需的Token echo "`head -c 16 /dev/urandom | od -An -t x | tr -d ' '`,kubelet-bootstrap,10001,"system:node-bootstrapper"" > /opt/k8s/cfg/token.csv #创建apiserver启动文件 cat > /usr/lib/systemd/system/kube-apiserver.service << EOF [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetesAfter=network.target [Service] EnvironmentFile=/opt/k8s/cfg/kube-apiserver.conf ExecStart=/opt/k8s/bin/kube-apiserver \$KUBE_APISERVER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl restart kube-apiserver systemctl enable kube-apiserver systemctl status kube-apiserver #部署kube-controller-manager #生成配置文件 cat > /opt/k8s/cfg/kube-controller-manager.conf << EOF KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/k8s/logs \\ --leader-elect=true \\ --kubeconfig=/opt/k8s/cfg/kube-controller-manager.kubeconfig \\ --bind-address=127.0.0.1 \\ --allocate-node-cidrs=true \\ --cluster-cidr=10.244.0.0/16 \\ --service-cluster-ip-range=10.0.0.0/24 \\ --cluster-signing-cert-file=/opt/k8s/ssl/ca.pem \\ --cluster-signing-key-file=/opt/k8s/ssl/ca-key.pem \\ --root-ca-file=/opt/k8s/ssl/ca.pem \\ --service-account-private-key-file=/opt/k8s/ssl/ca-key.pem \\ --cluster-signing-duration=87600h0m0s" EOF # –kubeconfig:连接apiserver配置文件 # –leader-elect:当该组件启动多个时,自动选举(HA) # –cluster-signing-cert-file/–cluster-signing-key-file:自动为kubelet颁发证书的CA,与apiserver保持一致 #生成kube-controller-manager.kubeconfig cd /data/TLS/k8s cat > kube-controller-manager-csr.json << EOF { "CN": "system:kube-controller-manager", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF # 生成证书 cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager #生成kube-controller-manager.kubeconfig文件 #生成kubeconfig文件(在/data/TLS/k8s下执行) KUBE_APISERVER="https://172.22.154.215:6443" KUBE_CONFIG="/opt/k8s/cfg/kube-controller-manager.kubeconfig" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials kube-controller-manager \ --client-certificate=./kube-controller-manager.pem \ --client-key=./kube-controller-manager-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user=kube-controller-manager \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG} #创建Kube-controller-manager启动文件 cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetesAfter=kube-apiserver.service [Service] EnvironmentFile=/opt/k8s/cfg/kube-controller-manager.conf ExecStart=/opt/k8s/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF #启动kube-controller-manager systemctl daemon-reload systemctl restart kube-controller-manager systemctl status kube-controller-manager systemctl enable kube-controller-manager ##部署kube-scheduler #生成配置文件 cat > /opt/k8s/cfg/kube-scheduler.conf << EOF KUBE_SCHEDULER_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/k8s/logs \\ --leader-elect \\ --kubeconfig=/opt/k8s/cfg/kube-scheduler.kubeconfig \\ --bind-address=127.0.0.1" EOF # –kubeconfig:连接apiserver配置文件 # –leader-elect:当该组件启动多个时,自动选举(HA) #生成kube-scheduler.kubeconfig cd /data/TLS/k8s # 创建证书请求文件 cat > kube-scheduler-csr.json << EOF { "CN": "system:kube-scheduler", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF # 生成证书 cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler #生成kubeconfig文件(在/data/TLS/k8s下执行) KUBE_CONFIG="/opt/k8s/cfg/kube-scheduler.kubeconfig" KUBE_APISERVER="https://172.22.154.215:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials kube-scheduler \ --client-certificate=./kube-scheduler.pem \ --client-key=./kube-scheduler-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user=kube-scheduler \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG} #创建kube-scheduler启动文件 cat > /usr/lib/systemd/system/kube-scheduler.service << EOF [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetesAfter=kube-apiserver.service [Service] EnvironmentFile=/opt/k8s/cfg/kube-scheduler.conf ExecStart=/opt/k8s/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF #启动kube-scheduer systemctl daemon-reload systemctl restart kube-scheduler systemctl status kube-scheduler systemctl enable kube-scheduler ##生成集群连接证书 cd /data/TLS/k8s cat > admin-csr.json <<EOF { "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin mkdir /root/.kube mkdir -pv /root/.kube KUBE_CONFIG="/root/.kube/config" KUBE_APISERVER="https://172.22.154.215:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials cluster-admin \ --client-certificate=./admin.pem \ --client-key=./admin-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user=cluster-admin \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG} #查看集群状态 kubectl get cs ###部署node节点 ##部署kubelet #生成kubelet配置文件 ###注意pause-amd镜像要放到私有仓库里 cat > /opt/k8s/cfg/kubelet.conf << EOF KUBELET_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/k8s/logs \\ --hostname-override=172.22.154.215 \\ --network-plugin=cni \\ --kubeconfig=/opt/k8s/cfg/kubelet.kubeconfig \\ --bootstrap-kubeconfig=/opt/k8s/cfg/bootstrap.kubeconfig \\ --config=/opt/k8s/cfg/kubelet-config.yml \\ --cert-dir=/opt/k8s/ssl \\ --pod-infra-container-image=harbor.local/pause-amd64:3.1" EOF # –hostname-override:显示名称,为节点hostname, 集群中唯一 # –network-plugin:启用CNI # –kubeconfig:空路径,会自动生成,后面用于连接apiserver # –bootstrap-kubeconfig:首次启动向apiserver申请证书 # –config:配置参数文件 # –cert-dir:kubelet证书生成目录 # –pod-infra-container-image:管理Pod网络容器的镜像 #创建kubelet-config.yaml文件 cat > /opt/k8s/cfg/kubelet-config.yml << EOF kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: - 10.0.0.2 clusterDomain: cluster.local failSwapOn: false authentication: anonymous: enabled: false webhook: cacheTTL: 2m0s enabled: true x509: clientCAFile: /opt/k8s/ssl/ca.pem authorization: mode: Webhook webhook: cacheAuthorizedTTL: 5m0s cacheUnauthorizedTTL: 30s evictionHard: imagefs.available: 15% memory.available: 100Mi nodefs.available: 10% nodefs.inodesFree: 5% maxOpenFiles: 1000000 maxPods: 110 EOF #kubelet初次加入集群引导kubeconfig文件 KUBE_CONFIG="/opt/k8s/cfg/bootstrap.kubeconfig" KUBE_APISERVER="https://172.22.154.215:6443" # 与token.csv里保持一致 TOKEN=`cat /opt/k8s/cfg/token.csv|awk -F',' '{print $1}'` # 生成 kubelet bootstrap kubeconfig 配置文件 kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials "kubelet-bootstrap" \ --token=${TOKEN} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user="kubelet-bootstrap" \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG} #创建Kubelet启动文件 cat > /usr/lib/systemd/system/kubelet.service << EOF [Unit] Description=Kubernetes Kubelet After=docker.service [Service] ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpu/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpuacct/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpuset/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/memory/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/pids/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/systemd/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpu/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpuacct/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/cpuset/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/memory/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/pids/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/systemd/system.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/hugetlb/podruntime.slice ExecStartPre=/bin/mkdir -p /sys/fs/cgroup/hugetlb/system.slice EnvironmentFile=/opt/k8s/cfg/kubelet.conf ExecStart=/opt/k8s/bin/kubelet \$KUBELET_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF ###为kubelet授权 kubectl create clusterrolebinding kubelet-bootstrap \ --clusterrole=system:node-bootstrapper \ --user=kubelet-bootstrap #启动kubelet systemctl daemon-reload systemctl restart kubelet systemctl status kubelet systemctl enable kubelet ###把文件同步到其它节点 rsync -av /opt/k8s/cfg/{kubelet.conf,kubelet-config.yml,bootstrap.kubeconfig} node216:/opt/k8s/cfg/ rsync -av /opt/k8s/cfg/{kubelet.conf,kubelet-config.yml,bootstrap.kubeconfig} node217:/opt/k8s/cfg/ ## 同步启动文件 rsync -av /usr/lib/systemd/system/kubelet.service root@node216:/usr/lib/systemd/system/kubelet.service rsync -av /usr/lib/systemd/system/kubelet.service root@node217:/usr/lib/systemd/system/kubelet.service ###记得修改kubelet.config中hostname-override ## 其余节点启动 systemctl daemon-reload systemctl restart kubelet systemctl status kubelet systemctl enable kubelet #批准节点加入集群 kubectl get csr NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-0WjKzlX1V8froo4Mgou1K2NruNVsMdgjUM2Ki6OnZHo 2m18s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending node-csr-UfbDWOmC82vJrdiHR2G2Agv-e0lTECTl8sxHPX-XLd8 2m8s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending node-csr-xEtbNTttO6HD9_pE6HmgjSus7iAkBbJrLLGuU1D2MU0 20s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending kubectl certificate approve node-csr-0WjKzlX1V8froo4Mgou1K2NruNVsMdgjUM2Ki6OnZHo kubectl certificate approve node-csr-UfbDWOmC82vJrdiHR2G2Agv-e0lTECTl8sxHPX-XLd8 kubectl certificate approve node-csr-xEtbNTttO6HD9_pE6HmgjSus7iAkBbJrLLGuU1D2MU0 ############错误展示####################### node217在启动Kubelet的时候没有修改config文件导致hostname冲突注册之后查看node并没有该节点 #停止Kubelet systemctl stop kubelet #修改config文件 vim /opt/k8s/cfg/kubelet.conf #删除kubelet.kubeconfig 该文件中包含了注册信息不删除无法重新注册 rm -rf /opt/k8s/cfg/kubelet.kubeconfig #重启Kubelet systemctl restart kubelet #再重新同意kubelet加入即可 ####部署kube-proxy #创建配置文件 cat > /opt/k8s/cfg/kube-proxy.conf << EOF KUBE_PROXY_OPTS=" --logtostderr=false \\ --v=2 \\ --log-dir=/opt/k8s/logs \\ --config=/opt/k8s/cfg/kube-proxy-config.yml" EOF #生成证书 cd /data/TLS/k8s # 创建证书请求文件 cat > kube-proxy-csr.json << EOF { "CN": "system:kube-proxy", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy #生成kube-proxy.kubeconfig文件 KUBE_CONFIG="/opt/k8s/cfg/kube-proxy.kubeconfig" KUBE_APISERVER="https://172.22.154.215:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials kube-proxy \ --client-certificate=./kube-proxy.pem \ --client-key=./kube-proxy-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user=kube-proxy \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG} #创建Kube-proxy-config.yaml文件 cat > /opt/k8s/cfg/kube-proxy-config.yml << EOF kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 bindAddress: 0.0.0.0 metricsBindAddress: 0.0.0.0:10249 clientConnection: kubeconfig: /opt/k8s/cfg/kube-proxy.kubeconfig hostnameOverride: 172.22.154.215 clusterCIDR: 10.0.0.0/24 EOF #创建kube-proxy启动文件 cat > /usr/lib/systemd/system/kube-proxy.service << EOF [Unit] Description=Kubernetes Proxy After=network.target [Service] EnvironmentFile=/opt/k8s/cfg/kube-proxy.conf ExecStart=/opt/k8s/bin/kube-proxy \$KUBE_PROXY_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF ## 同步kube-proxy配置 rsync -av /opt/k8s/cfg/{kube-proxy.conf,kube-proxy-config.yml,kube-proxy.kubeconfig} node216:/opt/k8s/cfg/ rsync -av /opt/k8s/cfg/{kube-proxy.conf,kube-proxy-config.yml,kube-proxy.kubeconfig} node217:/opt/k8s/cfg/ ## 同步启动文件 rsync -av /usr/lib/systemd/system/kube-proxy.service node216:/usr/lib/systemd/system/kube-proxy.service rsync -av /usr/lib/systemd/system/kube-proxy.service node217:/usr/lib/systemd/system/kube-proxy.service ####要记得修改Kube-proxy-config.yaml文件中hostnameOverride #启动kube-proxy systemctl daemon-reload systemctl restart kube-proxy systemctl enable kube-proxy systemctl status kube-proxy #授权apiserver访问kubelet cat > /opt/k8s/yaml/apiserver-to-kubelet-rbac.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-apiserver-to-kubelet rules: - apiGroups: - "" resources: - nodes/proxy - nodes/stats - nodes/log - nodes/spec - nodes/metrics - pods/log verbs: - "*" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:kube-apiserver namespace: "" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:kube-apiserver-to-kubelet subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kubernetes EOF kubectl apply -f apiserver-to-kubelet-rbac.yaml ###搭建私有镜像仓库 ###搭建镜像仓库会和ingress的443端口冲突,所以尽量不要复用 #添加解析 所有节点都要添加 IP替换为部署registry的节点IP vim /etc/hosts/ 172.22.154.215 harbor.local #容器镜像自行准备 #创建证书 mkdir -p certs openssl req \ -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \ -x509 -days 36500 -out certs/domain.crt #启动仓库 docker run -d \ --restart=always \ --name registry \ -v "$(pwd)"/certs:/certs \ -v /mnt/registry:/var/lib/registry \ -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ -p 443:443 \ registry:2 #把证书发到每一个节点 mkdir -p /etc/docker/certs.d/harbor.local/ cp certs/domain.crt /etc/docker/certs.d/harbor.local/ca.crt scp -r /etc/docker/certs.d node216:/etc/docker/ scp -r /etc/docker/certs.d node217:/etc/docker/ #上传所需的镜像 ###部署calico mkdir /opt/kubernetes/yaml cd /opt/kubernetes/yaml curl -k https://docs.projectcalico.org/manifests/calico-etcd.yaml -o calico-etcd.yaml vim calico.yaml ## etcd 证书 base64 地址 (执行里面的命令生成的证书 base64 码,填入里面) apiVersion: v1 kind: Secret type: Opaque metadata: name: calico-etcd-secrets namespace: kube-system data: etcd-key: "xxxxx执行结果"#(cat /opt/etcd/ssl/server-key.pem | base64 | tr -d '\n') ###这三个地方需要在shell界面执行完复制结果替换进来 etcd-cert:"xxxx" #(cat /opt/etcd/ssl/server.pem | base64 | tr -d '\n') etcd-ca: "xxx" #(cat /opt/etcd/ssl/ca.pem | base64 | tr -d '\n') ## 如上()中只是生成base64码的命令实际操作时需要去掉(),只需要填写生成的编码并用双引号引起来即可 ## ConfigMap ### 修改etcd地址 etcd_endpoints: "https://172.22.154.207:2379,https://172.22.154.207:2379,https://172.22.154.207:2379" ### 修改etcd证书位置 etcd_ca: "/calico-secrets/etcd-ca" etcd_cert: "/calico-secrets/etcd-cert" etcd_key: "/calico-secrets/etcd-key" ## 修改pod 分配的IP段(不能与node、service等地址同一网段) - name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16" --- # Source: calico/templates/calico-node-rbac.yaml # Include a clusterrole for the calico-node DaemonSet, # and bind it to the calico-node serviceaccount. kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: calico-node rules: # The CNI plugin needs to get pods, nodes, and namespaces. - apiGroups: [""] resources: - pods - nodes - namespaces verbs: - get # EndpointSlices are used for Service-based network policy rule # enforcement. - apiGroups: ["discovery.k8s.io"] resources: - endpointslices verbs: - watch - list - apiGroups: [""] resources: - endpoints - services verbs: # Used to discover service IPs for advertisement. - watch - list # Pod CIDR auto-detection on kubeadm needs access to config maps. - apiGroups: [""] resources: - configmaps verbs: - get - apiGroups: [""] resources: - nodes/status verbs: # Needed for clearing NodeNetworkUnavailable flag. - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: calico-node roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: calico-node subjects: - kind: ServiceAccount name: calico-node namespace: kube-system --- # Source: calico/templates/calico-node.yaml # This manifest installs the calico-node container, as well # as the CNI plugins and network config on # each master and worker node in a Kubernetes cluster. kind: DaemonSet apiVersion: apps/v1 metadata: name: calico-node namespace: kube-system labels: k8s-app: calico-node spec: selector: matchLabels: k8s-app: calico-node updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 template: metadata: labels: k8s-app: calico-node spec: nodeSelector: kubernetes.io/os: linux hostNetwork: true tolerations: # Make sure calico-node gets scheduled on all nodes. - effect: NoSchedule operator: Exists # Mark the pod as a critical add-on for rescheduling. - key: CriticalAddonsOnly operator: Exists - effect: NoExecute operator: Exists serviceAccountName: calico-node # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. terminationGracePeriodSeconds: 0 priorityClassName: system-node-critical initContainers: # This container installs the CNI binaries # and CNI network config file on each node. - name: install-cni image: docker.io/calico/cni:v3.20.2 command: ["/opt/cni/bin/install"] envFrom: - configMapRef: # Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode. name: kubernetes-services-endpoint optional: true env: # Name of the CNI config file to create. - name: CNI_CONF_NAME value: "10-calico.conflist" # The CNI network config to install on each node. - name: CNI_NETWORK_CONFIG valueFrom: configMapKeyRef: name: calico-config key: cni_network_config # The location of the etcd cluster. - name: ETCD_ENDPOINTS valueFrom: configMapKeyRef: name: calico-config key: etcd_endpoints # CNI MTU Config variable - name: CNI_MTU valueFrom: configMapKeyRef: name: calico-config key: veth_mtu # Prevents the container from sleeping forever. - name: SLEEP value: "false" volumeMounts: - mountPath: /host/opt/cni/bin name: cni-bin-dir - mountPath: /host/etc/cni/net.d name: cni-net-dir - mountPath: /calico-secrets name: etcd-certs securityContext: privileged: true # Adds a Flex Volume Driver that creates a per-pod Unix Domain Socket to allow Dikastes # to communicate with Felix over the Policy Sync API. - name: flexvol-driver image: docker.io/calico/pod2daemon-flexvol:v3.20.2 volumeMounts: - name: flexvol-driver-host mountPath: /host/driver securityContext: privileged: true containers: # Runs calico-node container on each Kubernetes node. This # container programs network policy and routes on each # host. - name: calico-node image: docker.io/calico/node:v3.20.2 envFrom: - configMapRef: # Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode. name: kubernetes-services-endpoint optional: true env: # The location of the etcd cluster. - name: ETCD_ENDPOINTS valueFrom: configMapKeyRef: name: calico-config key: etcd_endpoints # Location of the CA certificate for etcd. - name: ETCD_CA_CERT_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_ca # Location of the client key for etcd. - name: ETCD_KEY_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_key # Location of the client certificate for etcd. - name: ETCD_CERT_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_cert # Set noderef for node controller. - name: CALICO_K8S_NODE_REF valueFrom: fieldRef: fieldPath: spec.nodeName # Choose the backend to use. - name: CALICO_NETWORKING_BACKEND valueFrom: configMapKeyRef: name: calico-config key: calico_backend # Cluster type to identify the deployment type - name: CLUSTER_TYPE value: "k8s,bgp" # Auto-detect the BGP IP address. - name: IP value: "autodetect" # Enable IPIP - name: CALICO_IPV4POOL_IPIP value: "Always" # Enable or Disable VXLAN on the default IP pool. - name: CALICO_IPV4POOL_VXLAN value: "Never" # Set MTU for tunnel device used if ipip is enabled - name: FELIX_IPINIPMTU valueFrom: configMapKeyRef: name: calico-config key: veth_mtu # Set MTU for the VXLAN tunnel device. - name: FELIX_VXLANMTU valueFrom: configMapKeyRef: name: calico-config key: veth_mtu # Set MTU for the Wireguard tunnel device. - name: FELIX_WIREGUARDMTU valueFrom: configMapKeyRef: name: calico-config key: veth_mtu # The default IPv4 pool to create on startup if none exists. Pod IPs will be # chosen from this range. Changing this value after installation will have # no effect. This should fall within `--cluster-cidr`. - name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16" # Disable file logging so `kubectl logs` works. - name: CALICO_DISABLE_FILE_LOGGING value: "true" # Set Felix endpoint to host default action to ACCEPT. - name: FELIX_DEFAULTENDPOINTTOHOSTACTION value: "ACCEPT" # Disable IPv6 on Kubernetes. - name: FELIX_IPV6SUPPORT value: "false" - name: FELIX_HEALTHENABLED value: "true" securityContext: privileged: true resources: requests: cpu: 250m lifecycle: preStop: exec: command: - /bin/calico-node - -shutdown livenessProbe: exec: command: - /bin/calico-node - -felix-live - -bird-live periodSeconds: 10 initialDelaySeconds: 10 failureThreshold: 6 timeoutSeconds: 10 readinessProbe: exec: command: - /bin/calico-node - -felix-ready - -bird-ready periodSeconds: 10 timeoutSeconds: 10 volumeMounts: # For maintaining CNI plugin API credentials. - mountPath: /host/etc/cni/net.d name: cni-net-dir readOnly: false - mountPath: /lib/modules name: lib-modules readOnly: true - mountPath: /run/xtables.lock name: xtables-lock readOnly: false - mountPath: /var/run/calico name: var-run-calico readOnly: false - mountPath: /var/lib/calico name: var-lib-calico readOnly: false - mountPath: /calico-secrets name: etcd-certs - name: policysync mountPath: /var/run/nodeagent # For eBPF mode, we need to be able to mount the BPF filesystem at /sys/fs/bpf so we mount in the # parent directory. - name: sysfs mountPath: /sys/fs/ # Bidirectional means that, if we mount the BPF filesystem at /sys/fs/bpf it will propagate to the host. # If the host is known to mount that filesystem already then Bidirectional can be omitted. mountPropagation: Bidirectional - name: cni-log-dir mountPath: /var/log/calico/cni readOnly: true volumes: # Used by calico-node. - name: lib-modules hostPath: path: /lib/modules - name: var-run-calico hostPath: path: /var/run/calico - name: var-lib-calico hostPath: path: /var/lib/calico - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate - name: sysfs hostPath: path: /sys/fs/ type: DirectoryOrCreate # Used to install CNI. - name: cni-bin-dir hostPath: path: /opt/cni/bin - name: cni-net-dir hostPath: path: /etc/cni/net.d # Used to access CNI logs. - name: cni-log-dir hostPath: path: /var/log/calico/cni # Mount in the etcd TLS secrets with mode 400. # See https://kubernetes.io/docs/concepts/configuration/secret/ - name: etcd-certs secret: secretName: calico-etcd-secrets defaultMode: 0400 # Used to create per-pod Unix Domain Sockets - name: policysync hostPath: type: DirectoryOrCreate path: /var/run/nodeagent # Used to install Flex Volume Driver - name: flexvol-driver-host hostPath: type: DirectoryOrCreate path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds --- apiVersion: v1 kind: ServiceAccount metadata: name: calico-node namespace: kube-system --- # Source: calico/templates/calico-kube-controllers.yaml # See https://github.com/projectcalico/kube-controllers apiVersion: apps/v1 kind: Deployment metadata: name: calico-kube-controllers namespace: kube-system labels: k8s-app: calico-kube-controllers spec: # The controllers can only have a single active instance. replicas: 1 selector: matchLabels: k8s-app: calico-kube-controllers strategy: type: Recreate template: metadata: name: calico-kube-controllers namespace: kube-system labels: k8s-app: calico-kube-controllers spec: nodeSelector: kubernetes.io/os: linux tolerations: # Mark the pod as a critical add-on for rescheduling. - key: CriticalAddonsOnly operator: Exists - key: node-role.kubernetes.io/master effect: NoSchedule serviceAccountName: calico-kube-controllers priorityClassName: system-cluster-critical # The controllers must run in the host network namespace so that # it isn't governed by policy that would prevent it from working. hostNetwork: true containers: - name: calico-kube-controllers image: docker.io/calico/kube-controllers:v3.20.2 env: # The location of the etcd cluster. - name: ETCD_ENDPOINTS valueFrom: configMapKeyRef: name: calico-config key: etcd_endpoints # Location of the CA certificate for etcd. - name: ETCD_CA_CERT_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_ca # Location of the client key for etcd. - name: ETCD_KEY_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_key # Location of the client certificate for etcd. - name: ETCD_CERT_FILE valueFrom: configMapKeyRef: name: calico-config key: etcd_cert # Choose which controllers to run. - name: ENABLED_CONTROLLERS value: policy,namespace,serviceaccount,workloadendpoint,node volumeMounts: # Mount in the etcd TLS secrets. - mountPath: /calico-secrets name: etcd-certs livenessProbe: exec: command: - /usr/bin/check-status - -l periodSeconds: 10 initialDelaySeconds: 10 failureThreshold: 6 timeoutSeconds: 10 readinessProbe: exec: command: - /usr/bin/check-status - -r periodSeconds: 10 volumes: # Mount in the etcd TLS secrets with mode 400. # See https://kubernetes.io/docs/concepts/configuration/secret/ - name: etcd-certs secret: secretName: calico-etcd-secrets defaultMode: 0440 --- apiVersion: v1 kind: ServiceAccount metadata: name: calico-kube-controllers namespace: kube-system --- # This manifest creates a Pod Disruption Budget for Controller to allow K8s Cluster Autoscaler to evict apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: calico-kube-controllers namespace: kube-system labels: k8s-app: calico-kube-controllers spec: maxUnavailable: 1 selector: matchLabels: k8s-app: calico-kube-controllers --- # Source: calico/templates/calico-typha.yaml --- # Source: calico/templates/configure-canal.yaml --- # Source: calico/templates/kdd-crds.yaml kubectl apply -f calico.yaml #等pod都启动完毕查看node已经Ready ###部署coredns apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube-system labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: kubernetes.io/bootstrapping: rbac-defaults addonmanager.kubernetes.io/mode: Reconcile name: system:coredns rules: - apiGroups: - "" resources: - endpoints - services - pods - namespaces verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults addonmanager.kubernetes.io/mode: EnsureExists name: system:coredns roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:coredns subjects: - kind: ServiceAccount name: coredns namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance } --- apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "CoreDNS" spec: # replicas: not specified here: # 1. In order to make Addon Manager do not reconcile this replicas parameter. # 2. Default is 1. # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on. strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns annotations: seccomp.security.alpha.kubernetes.io/pod: 'runtime/default' spec: priorityClassName: system-cluster-critical serviceAccountName: coredns tolerations: - key: "CriticalAddonsOnly" operator: "Exists" nodeSelector: kubernetes.io/os: linux containers: - name: coredns image: coredns/coredns:1.8.0 imagePullPolicy: IfNotPresent resources: limits: memory: 160Mi requests: cpu: 100m memory: 70Mi args: [ "-conf", "/etc/coredns/Corefile" ] volumeMounts: - name: config-volume mountPath: /etc/coredns readOnly: true ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP - containerPort: 9153 name: metrics protocol: TCP livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /ready port: 8181 scheme: HTTP securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_BIND_SERVICE drop: - all readOnlyRootFilesystem: true dnsPolicy: Default volumes: - name: config-volume configMap: name: coredns items: - key: Corefile path: Corefile --- apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system annotations: prometheus.io/port: "9153" prometheus.io/scrape: "true" labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.0.0.2 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP - name: metrics port: 9153 protocol: TCP ###部署ingress-nginx apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nginx-ingress-controller labels: app: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets - namespaces - services verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses/status verbs: - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - configmaps resourceNames: - "ingress-controller-leader-nginx" verbs: - get - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nginx-ingress-controller labels: app: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-controller subjects: - kind: ServiceAccount name: nginx-ingress-controller namespace: ingress-nginx --- apiVersion: v1 kind: Service metadata: labels: app: ingress-nginx name: nginx-ingress-lb namespace: ingress-nginx spec: # DaemonSet need: # ---------------- type: ClusterIP # ---------------- # Deployment need: # ---------------- # type: NodePort # ---------------- ports: - name: http port: 80 targetPort: 80 protocol: TCP - name: https port: 443 targetPort: 443 protocol: TCP - name: metrics port: 10254 protocol: TCP targetPort: 10254 selector: app: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app: ingress-nginx data: keep-alive: "75" keep-alive-requests: "100" upstream-keepalive-connections: "10000" upstream-keepalive-requests: "100" upstream-keepalive-timeout: "60" allow-backend-server-header: "true" enable-underscores-in-headers: "true" generate-request-id: "true" http-redirect-code: "301" ignore-invalid-headers: "true" log-format-upstream: '{"@timestamp": "$time_iso8601","remote_addr": "$remote_addr","x-forward-for": "$proxy_add_x_forwarded_for","request_id": "$req_id","remote_user": "$remote_user","bytes_sent": $bytes_sent,"request_time": $request_time,"status": $status,"vhost": "$host","request_proto": "$server_protocol","path": "$uri","request_query": "$args","request_length": $request_length,"duration": $request_time,"method": "$request_method","http_referrer": "$http_referer","http_user_agent": "$http_user_agent","upstream-sever":"$proxy_upstream_name","proxy_alternative_upstream_name":"$proxy_alternative_upstream_name","upstream_addr":"$upstream_addr","upstream_response_length":$upstream_response_length,"upstream_response_time":$upstream_response_time,"upstream_status":$upstream_status}' max-worker-connections: "65536" worker-processes: "2" proxy-body-size: 20m proxy-connect-timeout: "10" proxy_next_upstream: error timeout http_502 reuse-port: "true" server-tokens: "false" ssl-ciphers: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA ssl-protocols: TLSv1 TLSv1.1 TLSv1.2 ssl-redirect: "false" worker-cpu-affinity: auto --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app: ingress-nginx --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app: ingress-nginx annotations: component.version: "v0.30.0" component.revision: "v1" spec: # Deployment need: # ---------------- # replicas: 1 # ---------------- selector: matchLabels: app: ingress-nginx template: metadata: labels: app: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" scheduler.alpha.kubernetes.io/critical-pod: "" spec: # DaemonSet need: # ---------------- hostNetwork: true # ---------------- serviceAccountName: nginx-ingress-controller priorityClassName: system-node-critical affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - ingress-nginx topologyKey: kubernetes.io/hostname weight: 100 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: type operator: NotIn values: - virtual-kubelet containers: - name: nginx-ingress-controller image: registry.cn-beijing.aliyuncs.com/acs/aliyun-ingress-controller:v0.30.0.2-9597b3685-aliyun args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb - --annotations-prefix=nginx.ingress.kubernetes.io - --enable-dynamic-certificates=true - --v=2 securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 443 livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 # resources: # limits: # cpu: "1" # memory: 2Gi # requests: # cpu: "1" # memory: 2Gi volumeMounts: - mountPath: /etc/localtime name: localtime readOnly: true volumes: - name: localtime hostPath: path: /etc/localtime type: File tolerations: - operator: Exists initContainers: - command: - /bin/sh - -c - | mount -o remount rw /proc/sys sysctl -w net.core.somaxconn=65535 sysctl -w net.ipv4.ip_local_port_range="1024 65535" sysctl -w fs.file-max=1048576 sysctl -w fs.inotify.max_user_instances=16384 sysctl -w fs.inotify.max_user_watches=524288 sysctl -w fs.inotify.max_queued_events=16384 image: registry.cn-beijing.aliyuncs.com/acs/busybox:v1.29.2 imagePullPolicy: IfNotPresent name: init-sysctl securityContext: privileged: true procMount: Default ###etcd备份数据 cp etcdctl /usr/bin/ #查看etcd状态 ETCDCTL_API=3 etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints=https://172.22.154.215:2379,https://172.22.154.216:2379,https://172.22.154.217:2379 endpoint health 备份数据 ETCDCTL_API=3 etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints=https://172.22.154.215:2379 snapshot save /data/etcd_backup_dir/etcd-snapshot-`date +%Y%m%d`.db 备份脚本 ####为避免集群服务器崩溃建议将备份数据在其它服务器上也存储一份! #!/usr/bin/env bash date; CACERT="/opt/etcd/ssl/ca.pem" CERT="/opt/etcd/ssl/server.pem" EKY="/opt/etcd/ssl/server-key.pem" ENDPOINTS="172.22.154.215:2379" ETCDCTL_API=3 etcdctl \ --cacert="${CACERT}" --cert="${CERT}" --key="${EKY}" \ --endpoints=${ENDPOINTS} \ snapshot save /data/etcd_backup_dir/etcd-snapshot-`date +%Y%m%d`.db # 备份保留30天 find /data/etcd_backup_dir/ -name *.db -mtime +30 -exec rm -f {} \;