<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    手把手教你部署一個最小化的 Kubernetes 集群!

    一顆小胡椒2022-03-23 06:16:08

    雖然網上有大量從零搭建 K8S 的文章,但大都針對老版本,若直接照搬去安裝最新的 1.20 版本會遇到一堆問題。故此將我的安裝步驟記錄下來,希望能為讀者提供 copy and paste 式的集群搭建幫助。

    1. 部署準備工作

    部署最小化 K8S 集群:master + node1 + node2

    Ubuntu 是一款基于 Debian Linux 的以桌面應用為主的操作系統,內容涵蓋文字處理、電子郵件、軟件開發工具和 Web 服務等,可供用戶免費下載、使用和分享。

    ? vgs
    Current machine states:
    master                    running (virtualbox)
    node1                     running (virtualbox)
    node2                     running (virtualbox)
    

    1.1 基礎環境信息

    設置系統主機名以及 Host 文件各節點之間的相互解析

    • 使用這個的 Vagrantfile 啟動的三節點服務已經配置好了
    • 以下使用 master 節點進行演示查看,其他節點操作均一致
    # hostnamectl
    vagrant@k8s-master:~$ hostnamectl
       Static hostname: k8s-master
    # hosts
    vagrant@k8s-master:~$ cat /etc/hosts
    127.0.0.1        localhost
    127.0.1.1        vagrant.vm    vagrant
    192.168.30.30    k8s-master
    192.168.30.31    k8s-node1
    192.168.30.32    k8s-node2
    # ping
    vagrant@k8s-master:~$ ping k8s-node1
    PING k8s-node1 (192.168.30.31) 56(84) bytes of data.
    64 bytes from k8s-node1 (192.168.30.31): icmp_seq=1 ttl=64 time=0.689 ms
    

    1.2 阿里源配置

    配置 Ubuntu 的阿里源來加速安裝速度

    • 阿里源鏡像地址
    # 登錄服務器
    ? vgssh master/node1/nod2
    Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-50-generic x86_64)
    # 設置阿里云Ubuntu鏡像
    $ sudo cp /etc/apt/sources.list{,.bak}
    $ sudo vim /etc/apt/sources.list
    # 配置kubeadm的阿里云鏡像源
    $ sudo vim /etc/apt/sources.list
    deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
    $ sudo gpg --keyserver keyserver.ubuntu.com --recv-keys BA07F4FB
    $ sudo gpg --export --armor BA07F4FB | sudo apt-key add -
    # 配置docker安裝
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    $ sudo apt-key fingerprint 0EBFCD88
    $ sudo vim /etc/apt/sources.list
    deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable
    # 更新倉庫
    $ sudo apt update
    $ sudo apt dist-upgrade
    

    1.3 基礎工具安裝

    部署階段的基礎工具安裝

    • 基礎組件 docker
    • 部署工具 kubeadm
    • 路由規則 ipvsadm
    • 時間同步 ntp
    # 基礎工具安裝
    $ sudo apt install -y \
        docker-ce docker-ce-cli containerd.io \
        kubeadm ipvsadm \
        ntp ntpdate \
        nginx supervisor
    # 將當前普通用戶加入docker組(需重新登錄)
    $ sudo usermod -a -G docker $USER
    # 服務啟用
    $ sudo systemctl enable docker.service
    $ sudo systemctl start docker.service
    $ sudo systemctl enable kubelet.service
    $ sudo systemctl start kubelet.service
    

    1.4 操作系統配置

    操作系統相關配置

    • 關閉緩存
    • 配置內核參數
    • 調整系統時區
    • 升級內核版本(默認為4.15.0的版本)
    # 關閉緩存
    $ sudo swapoff -a
    # 為K8S來調整內核參數
    $ sudo touch /etc/sysctl.d/kubernetes.conf
    $ sudo cat > /etc/sysctl.d/kubernetes.conf <net.bridge.bridge-nf-call-iptables = 1 # 開啟網橋模式(必須)
    net.bridge.bridge-nf-call-ip6tables = 1 # 開啟網橋模式(必須)
    net.ipv6.conf.all.disable_ipv6 = 1 # 關閉IPv6協議(必須)
    net.ipv4.ip_forward = 1 # 轉發模式(默認開啟)
    vm.panic_on_oom=0 # 開啟OOM(默認開啟)
    vm.swappiness = 0 # 禁止使用swap空間
    vm.overcommit_memory=1 # 不檢查物理內存是否夠用
    fs.inotify.max_user_instances=8192
    fs.inotify.max_user_watches=1048576
    fs.file-max = 52706963 # 設置文件句柄數量
    fs.nr_open = 52706963 # 設置文件的最大打開數量
    net.netfilter.nf_conntrack_max = 2310720
    EOF
    # 查看系統內核參數的方式
    $ sudo sysctl -a | grep xxx
    # 使內核參數配置文件生效
    $ sudo sysctl -p /etc/sysctl.d/kubernetes.conf
    # 設置系統時區為中國/上海
    $ sudo timedatectl set-timezone Asia/Shanghai
    # 將當前的UTC時間寫入硬件時鐘
    $ sudo timedatectl set-local-rtc 0
    

    1.5 開啟 ipvs 服務

    開啟 ipvs 服務

    • kube-proxy 開啟 ipvs 的前置條件
    # 載入指定的個別模塊
    $ modprobe br_netfilter
    # 修改配置
    $ cat > /etc/sysconfig/modules/ipvs.modules <#!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv
    EOF
    # 加載配置
    $ chmod 755 /etc/sysconfig/modules/ipvs.modules \
        && bash /etc/sysconfig/modules/ipvs.modules \
        && lsmod | grep -e ip_vs -e nf_conntrack_ipv
    

    2. 部署 Master 節點

    節點最低配置: 2C+2G 內存;從節點資源盡量充足

    kubeadm 工具的 init 命令,即可初始化以單節點部署的 master。為了避免翻墻,這里可以使用阿里云的谷歌源來代替。在執行 kubeadm 部署命令的時候,指定對應地址即可。當然,可以將其加入本地的鏡像庫之中,更易維護。

    注意事項

    • 阿里云谷歌源地址
    • 使用 kubeadm 定制控制平面配置
    # 登錄服務器
    ? vgssh master
    Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-50-generic x86_64)
    # 部署節點(命令行)
    # 注意pod和service的地址需要不同(否則會報錯)
    $ sudo kubeadm init \
        --kubernetes-version=1.20.2 \
        --image-repository registry.aliyuncs.com/google_containers \
        --apiserver-advertise-address=192.168.30.30 \
        --pod-network-cidr=10.244.0.0/16 \
        --service-cidr=10.245.0.0/16
    # 部署鏡像配置(配置文件)
    $ sudo kubeadm init --config ./kubeadm-config.yaml
    Your Kubernetes control-plane has initialized successfully!
    # 查看IP段是否生效(iptable)
    $ ip route show
    10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1
    10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink
    10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
    # # 查看IP段是否生效(ipvs)
    $ ipvsadm -L -n
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    

    配置文件定義

    • 接口使用了 v1beta2 版本
    • 配置主節點 IP 地址為 192.168.30.30
    • 為 flannel 分配的是 10.244.0.0/16 網段
    • 選擇的 kubernetes 是當前最新的 1.20.2 版本
    • 加入了 controllerManager 的水平擴容功能
    # kubeadm-config.yaml
    # sudo kubeadm config print init-defaults > kubeadm-config.yaml
    apiVersion: kubeadm.k8s.io/v1beta2
    imageRepository: registry.aliyuncs.com/google_containers
    kind: ClusterConfiguration
    kubernetesVersion: v1.20.2
    apiServer:
      extraArgs:
        advertise-address: 192.168.30.30
    networking:
      podSubnet: 10.244.0.0/16
    controllerManager:
      ExtraArgs:
        horizontal-pod-autoscaler-use-rest-clients: "true"
        horizontal-pod-autoscaler-sync-period: "10s"
        node-monitor-grace-period: "10s"
    

    執行成功之后會輸出如下信息,需要安裝如下步驟操作下

    第一步 在 kubectl 默認控制和操作集群節點的時候,需要使用到 CA 的密鑰,傳輸過程是通過 TLS 協議保障通訊的安全性。通過下面 3 行命令拷貝密鑰信息到當前用戶家目錄下,這樣 kubectl 執行時會首先訪問 .kube 目錄,使用這些授權信息訪問集群。

    第二步 之后添加 worker 節點時,要通過 token 才能保障安全性。因此,先把顯示的這行命令保存下來,以備后續使用會用到。

    # master setting step one
    To start cluster, you need to run the following as a regular user:
      mkdir -p $HOME/.kube
      sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      sudo chown $(id -u):$(id -g) $HOME/.kube/config
    Alternatively, if you are the root user, you can run:
      export KUBECONFIG=/etc/kubernetes/admin.conf
    # master setting step two
    You should now deploy a pod network to the cluster.
    Run "kubectl apply -f [podnetwork].yaml" with one of the options listed:
      https://kubernetes.io/docs/concepts/cluster-administration/addons/
    Join any number of worker nodes by running the following on each as root:
    kubeadm join 192.168.30.30:6443 \
      --token lebbdi.p9lzoy2a16tmr6hq \
      --discovery-token-ca-cert-hash \
      sha256:6c79fd83825d7b2b0c3bed9e10c428acf8ffcd615a1d7b258e9b500848c20cae
    

    將子節點加入主節點中

    $ kubectl get nodes
    NAME         STATUS     ROLES                  AGE   VERSION
    k8s-master   NotReady   control-plane,master   62m   v1.20.2
    k8s-node1    NotReady                    82m   v1.20.2
    k8s-node2    NotReady                    82m   v1.20.2
    # 查看token令牌
    $ sudo kubeadm token list
    # 生成token令牌
    $ sudo kubeadm token create
    # 忘記sha編碼
    $ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
        | openssl rsa -pubin -outform der 2>/dev/null \
        | openssl dgst -sha256 -hex | sed 's/^.* //'
    # 生成一個新的 token 令牌(比上面的方便)
    $ kubeadm token generate
    # 直接生成 join 命令(比上面的方便)
    $ kubeadm token create  --print-join-command --ttl=0
    

    執行完成之后可以通過如下命令,查看主節點信息

    默認生成四個命名空間

    • default、kube-system、kube-public、kube-node-lease

    部署的核心服務有以下幾個 (kube-system)

    • coredns、etcd
    • kube-apiserver、kube-scheduler
    • kube-controller-manager、kube-controller-manager

    此時 master 并沒有 ready 狀態(需要安裝網絡插件),下一章節中,我們將安裝 flannel 這個網絡插件

    # 命名空間
    $ kubectl get namespace
    NAME              STATUS   AGE
    default           Active   19m
    kube-node-lease   Active   19m
    kube-public       Active   19m
    kube-system       Active   19m
    # 核心服務
    $ kubectl get pod -n kube-system
    NAME                                 READY   STATUS    RESTARTS   AGE
    coredns-7f89b7bc75-bh42f             1/1     Running   0          19m
    coredns-7f89b7bc75-dvzpl             1/1     Running   0          19m
    etcd-k8s-master                      1/1     Running   0          19m
    kube-apiserver-k8s-master            1/1     Running   0          19m
    kube-controller-manager-k8s-master   1/1     Running   0          19m
    kube-proxy-5rlpv                     1/1     Running   0          19m
    kube-scheduler-k8s-master            1/1     Running   0          19m
    

    3. 部署 flannel 網絡

    網絡服務用于管理 K8S 集群中的服務網絡

    flannel 網絡需要指定 IP 地址段,即上一步中通過編排文件設置的 10.244.0.0/16。其實可以通過 flannel 官方和 HELM 工具直接部署服務,但是原地址是需要搭梯子的。所以,可以將其內容保存在如下配置文件中,修改對應鏡像地址。

    部署 flannel 服務的官方下載地址

    # 部署flannel服務
    # 1.修改鏡像地址(如果下載不了的話)
    # 2.修改Network為--pod-network-cidr的參數IP段
    $ kubectl apply -f ./kube-flannel.yml
    # 如果部署出現問題可通過如下命令查看日志
    $ kubectl logs kube-flannel-ds-6xxs5 --namespace=kube-system
    $ kubectl describe pod kube-flannel-ds-6xxs5 --namespace=kube-system
    

    如果使用當中存在問題的,可以參考官方的問題手冊

    因為我們這里使用的是 Vagrant 虛擬出來的機器進行 K8S 的部署,但是在運行對應 yaml 配置的時候,會報錯。通過查看日志發現是因為默認綁定的是虛擬機上面的 eth0 這塊網卡,而這塊網卡是 Vagrant 使用的,我們應該綁定的是 eth1 才對。

    Vagrant 通常為所有 VM 分配兩個接口,第一個為所有主機分配的 IP 地址為 10.0.2.15,用于獲得 NAT 的外部流量。這樣會導致 flannel 部署存在問題。通過官方問題說明,我們可以使用 --iface=eth1 這個參數選擇第二個網卡。

    對應的參數使用方式,可以參考 flannel use –iface=eth1 中的回答自行添加,而這里我直接修改了啟動的配置文件,在啟動服務的時候通過 args 修改了,如下所示。

    $ kubectl get pods -n kube-system
    NAME                                 READY   STATUS    RESTARTS   AGE
    coredns-7f89b7bc75-bh42f             1/1     Running   0          61m
    coredns-7f89b7bc75-dvzpl             1/1     Running   0          61m
    etcd-k8s-master                      1/1     Running   0          62m
    kube-apiserver-k8s-master            1/1     Running   0          62m
    kube-controller-manager-k8s-master   1/1     Running   0          62m
    kube-flannel-ds-zl148                1/1     Running   0          44s
    kube-flannel-ds-ll523                1/1     Running   0          44s
    kube-flannel-ds-wpmhw                1/1     Running   0          44s
    kube-proxy-5rlpv                     1/1     Running   0          61m
    kube-scheduler-k8s-master            1/1     Running   0          62m
    

    配置文件如下所示

    ---
    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: psp.flannel.unprivileged
      annotations:
        seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
        seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
        apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
        apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
    spec:
      privileged: false
      volumes:
        - configMap
        - secret
        - emptyDir
        - hostPath
      allowedHostPaths:
        - pathPrefix: "/etc/cni/net.d"
        - pathPrefix: "/etc/kube-flannel"
        - pathPrefix: "/run/flannel"
      readOnlyRootFilesystem: false
      # Users and groups
      runAsUser:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      fsGroup:
        rule: RunAsAny
      # Privilege Escalation
      allowPrivilegeEscalation: false
      defaultAllowPrivilegeEscalation: false
      # Capabilities
      allowedCapabilities: ["NET_ADMIN", "NET_RAW"]
      defaultAddCapabilities: []
      requiredDropCapabilities: []
      # Host namespaces
      hostPID: false
      hostIPC: false
      hostNetwork: true
      hostPorts:
        - min: 0
          max: 65535
      # SELinux
      seLinux:
        # SELinux is unused in CaaSP
        rule: "RunAsAny"
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: flannel
    rules:
      - apiGroups: ["extensions"]
        resources: ["podsecuritypolicies"]
        verbs: ["use"]
        resourceNames: ["psp.flannel.unprivileged"]
      - apiGroups:
          - ""
        resources:
          - pods
        verbs:
          - get
      - apiGroups:
          - ""
        resources:
          - nodes
        verbs:
          - list
          - watch
      - apiGroups:
          - ""
        resources:
          - nodes/status
        verbs:
          - patch
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: flannel
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: flannel
    subjects:
      - kind: ServiceAccount
        name: flannel
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: flannel
      namespace: kube-system
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: kube-flannel-cfg
      namespace: kube-system
      labels:
        tier: node
        app: flannel
    data:
      cni-conf.json: |
        {
          "name": "cbr0",
          "cniVersion": "0.3.1",
          "plugins": [
            {
              "type": "flannel",
              "delegate": {
                "hairpinMode": true,
                "isDefaultGateway": true
              }
            },
            {
              "type": "portmap",
              "capabilities": {
                "portMappings": true
              }
            }
          ]
        }
      net-conf.json: |
        {
          "Network": "10.244.0.0/16",
          "Backend": {
            "Type": "vxlan"
          }
        }
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: kube-flannel-ds
      namespace: kube-system
      labels:
        tier: node
        app: flannel
    spec:
      selector:
        matchLabels:
          app: flannel
      template:
        metadata:
          labels:
            tier: node
            app: flannel
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: kubernetes.io/os
                        operator: In
                        values:
                          - linux
          hostNetwork: true
          priorityClassName: system-node-critical
          tolerations:
            - operator: Exists
              effect: NoSchedule
          serviceAccountName: flannel
          initContainers:
            - name: install-cni
              image: quay.io/coreos/flannel:v0.13.1-rc1
              command:
                - cp
              args:
                - -f
                - /etc/kube-flannel/cni-conf.json
                - /etc/cni/net.d/10-flannel.conflist
              volumeMounts:
                - name: cni
                  mountPath: /etc/cni/net.d
                - name: flannel-cfg
                  mountPath: /etc/kube-flannel/
          containers:
            - name: kube-flannel
              image: quay.io/coreos/flannel:v0.13.1-rc1
              command:
                - /opt/bin/flanneld
              args:
                - --ip-masq
                - --kube-subnet-mgr
                - --iface=eth1
              resources:
                requests:
                  cpu: "100m"
                  memory: "50Mi"
                limits:
                  cpu: "100m"
                  memory: "50Mi"
              securityContext:
                privileged: false
                capabilities:
                  add: ["NET_ADMIN", "NET_RAW"]
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
                - name: POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.namespace
              volumeMounts:
                - name: run
                  mountPath: /run/flannel
                - name: flannel-cfg
                  mountPath: /etc/kube-flannel/
          volumes:
            - name: run
              hostPath:
                path: /run/flannel
            - name: cni
              hostPath:
                path: /etc/cni/net.d
            - name: flannel-cfg
              configMap:
                name: kube-flannel-cfg
    

    至此集群部署成功!如果有參數錯誤需要修改,你也可以在 reset 后重新 init 集群。

    $ kubectl get nodes
    NAME         STATUS   ROLES                  AGE   VERSION
    k8s-master   Ready    control-plane,master   62m   v1.20.2
    k8s-node1    Ready    control-plane,master   82m   v1.20.2
    k8s-node2    Ready    control-plane,master   82m   v1.20.2
    # 重啟集群
    $ sudo kubeadm reset
    $ sudo kubeadm init
    

    4. 部署 dashboard 服務

    以 WEB 頁面的可視化 dashboard 來監控集群的狀態

    這個還是會遇到需要搭梯子下載啟動配置文件的問題,下面是對應的下載地址,可以下載之后上傳到服務器上面在進行部署。

    部署 dashboard 服務的官方下載地址

    # 部署flannel服務
    $ kubectl apply -f ./kube-dashboard.yaml
    # 如果部署出現問題可通過如下命令查看日志
    $ kubectl logs \
        kubernetes-dashboard-c9fb67ffc-nknpj \
        --namespace=kubernetes-dashboard
    $ kubectl describe pod \
        kubernetes-dashboard-c9fb67ffc-nknpj \
        --namespace=kubernetes-dashboard
    $ kubectl get svc -n kubernetes-dashboard
    NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    dashboard-metrics-scraper   ClusterIP   10.245.214.11    <none>        8000/TCP   26s
    kubernetes-dashboard        ClusterIP   10.245.161.146   <none>        443/TCP    26s
    

    需要注意的是 dashboard 默認不允許外網訪問,即使通過 kubectl proxy 允許外網訪問。但 dashboard 又只允許 HTTPS 訪問,這樣 kubeadm init 時自簽名的 CA 證書是不被瀏覽器承認的。

    我采用的方案是 Nginx 作為反向代理,使用 Lets Encrypt 提供的有效證書對外提供服務,再經由 proxy_pass 指令反向代理到 kubectl proxy 上,如下所示。此時,本地可經由 8888 訪問到 dashboard 服務,再通過 Nginx 訪問它。

    # 代理(可以使用supervisor)
    $ kubectl proxy --accept-hosts='^*$'
    $ kubectl proxy --port=8888 --accept-hosts='^*$'
    # 測試代理是否正常(默認監聽在8001端口上)
    $ curl -X GET -L http://localhost:8001
    # 本地(可以使用nginx)
    proxy_pass http://localhost:8001;
    proxy_pass http://localhost:8888;
    # 外網訪問如下URL地址
    https://mydomain/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
    

    配置文件整理

    • nginx
    • supervisor
    # k8s.conf
    client_max_body_size     80M;
    client_body_buffer_size  128k;
    proxy_connect_timeout    600;
    proxy_read_timeout       600;
    proxy_send_timeout       600;
    server {
        listen       8080 ssl;
        server_name  _;
        ssl_certificate     /etc/kubernetes/pki/ca.crt;
        ssl_certificate_key /etc/kubernetes/pki/ca.key;
        access_log /var/log/nginx/k8s.access.log;
        error_log  /var/log/nginx/k8s.error.log  error;
        location / {
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_pass http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/;
        }
    }
    # k8s.conf
    [program:k8s-master]
    command=kubectl proxy --accept-hosts='^*$'
    user=vagrant
    environment=KUBECONFIG="/home/vagrant/.kube/config"
    stopasgroup=true
    stopasgroup=true
    autostart=true
    autorestart=unexpected
    stdout_logfile_maxbytes=1MB
    stdout_logfile_backups=10
    stderr_logfile_maxbytes=1MB
    stderr_logfile_backups=10
    stderr_logfile=/var/log/supervisor/k8s-stderr.log
    stdout_logfile=/var/log/supervisor/k8s-stdout.log
    

    配置文件如下所示

    # Copyright 2017 The Kubernetes Authors.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    apiVersion: v1
    kind: Namespace
    metadata:
      name: kubernetes-dashboard
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    spec:
      ports:
        - port: 443
          targetPort: 8443
      selector:
        k8s-app: kubernetes-dashboard
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard-certs
      namespace: kubernetes-dashboard
    type: Opaque
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard-csrf
      namespace: kubernetes-dashboard
    type: Opaque
    data:
      csrf: ""
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard-key-holder
      namespace: kubernetes-dashboard
    type: Opaque
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard-settings
      namespace: kubernetes-dashboard
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    rules:
      # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
      - apiGroups: [""]
        resources: ["secrets"]
        resourceNames:
          [
            "kubernetes-dashboard-key-holder",
            "kubernetes-dashboard-certs",
            "kubernetes-dashboard-csrf",
          ]
        verbs: ["get", "update", "delete"]
        # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
      - apiGroups: [""]
        resources: ["configmaps"]
        resourceNames: ["kubernetes-dashboard-settings"]
        verbs: ["get", "update"]
        # Allow Dashboard to get metrics.
      - apiGroups: [""]
        resources: ["services"]
        resourceNames: ["heapster", "dashboard-metrics-scraper"]
        verbs: ["proxy"]
      - apiGroups: [""]
        resources: ["services/proxy"]
        resourceNames:
          [
            "heapster",
            "http:heapster:",
            "https:heapster:",
            "dashboard-metrics-scraper",
            "http:dashboard-metrics-scraper",
          ]
        verbs: ["get"]
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
    rules:
      # Allow Metrics Scraper to get metrics from the Metrics server
      - apiGroups: ["metrics.k8s.io"]
        resources: ["pods", "nodes"]
        verbs: ["get", "list", "watch"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: kubernetes-dashboard
    subjects:
      - kind: ServiceAccount
        name: kubernetes-dashboard
        namespace: kubernetes-dashboard
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: kubernetes-dashboard
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: kubernetes-dashboard
    subjects:
      - kind: ServiceAccount
        name: kubernetes-dashboard
        namespace: kubernetes-dashboard
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          k8s-app: kubernetes-dashboard
      template:
        metadata:
          labels:
            k8s-app: kubernetes-dashboard
        spec:
          containers:
            - name: kubernetes-dashboard
              image: registry.cn-shanghai.aliyuncs.com/jieee/dashboard:v2.0.4
              imagePullPolicy: Always
              ports:
                - containerPort: 8443
                  protocol: TCP
              args:
                - --auto-generate-certificates
                - --namespace=kubernetes-dashboard
                # Uncomment the following line to manually specify Kubernetes API server Host
                # If not specified, Dashboard will attempt to auto discover the API server and connect
                # to it. Uncomment only if the default does not work.
                # - --apiserver-host=http://my-address:port
              volumeMounts:
                - name: kubernetes-dashboard-certs
                  mountPath: /certs
                  # Create on-disk volume to store exec logs
                - mountPath: /tmp
                  name: tmp-volume
              livenessProbe:
                httpGet:
                  scheme: HTTPS
                  path: /
                  port: 8443
                initialDelaySeconds: 30
                timeoutSeconds: 30
              securityContext:
                allowPrivilegeEscalation: false
                readOnlyRootFilesystem: true
                runAsUser: 1001
                runAsGroup: 2001
          volumes:
            - name: kubernetes-dashboard-certs
              secret:
                secretName: kubernetes-dashboard-certs
            - name: tmp-volume
              emptyDir: {}
          serviceAccountName: kubernetes-dashboard
          nodeSelector:
            "kubernetes.io/os": linux
          # Comment the following tolerations if Dashboard must not be deployed on master
          tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: dashboard-metrics-scraper
      name: dashboard-metrics-scraper
      namespace: kubernetes-dashboard
    spec:
      ports:
        - port: 8000
          targetPort: 8000
      selector:
        k8s-app: dashboard-metrics-scraper
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      labels:
        k8s-app: dashboard-metrics-scraper
      name: dashboard-metrics-scraper
      namespace: kubernetes-dashboard
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          k8s-app: dashboard-metrics-scraper
      template:
        metadata:
          labels:
            k8s-app: dashboard-metrics-scraper
          annotations:
            seccomp.security.alpha.kubernetes.io/pod: "runtime/default"
        spec:
          containers:
            - name: dashboard-metrics-scraper
              image: registry.cn-shanghai.aliyuncs.com/jieee/metrics-scraper:v1.0.4
              ports:
                - containerPort: 8000
                  protocol: TCP
              livenessProbe:
                httpGet:
                  scheme: HTTP
                  path: /
                  port: 8000
                initialDelaySeconds: 30
                timeoutSeconds: 30
              volumeMounts:
                - mountPath: /tmp
                  name: tmp-volume
              securityContext:
                allowPrivilegeEscalation: false
                readOnlyRootFilesystem: true
                runAsUser: 1001
                runAsGroup: 2001
          serviceAccountName: kubernetes-dashboard
          nodeSelector:
            "kubernetes.io/os": linux
          # Comment the following tolerations if Dashboard must not be deployed on master
          tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
          volumes:
            - name: tmp-volume
              emptyDir: {}
    

    第一種:登錄 dashboard 的方式(配置文件)

    • 采用 token 方式
    • 采用秘鑰文件方式

    # 創建管理員帳戶(dashboard)
    $ cat <apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: admin-user
      namespace: kubernetes-dashboard
    EOF
    # 將用戶綁定已經存在的集群管理員角色
    $ cat <apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: admin-user
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: ServiceAccount
      name: admin-user
      namespace: kubernetes-dashboard
    EOF
    # 獲取可用戶于訪問的token令牌
    $ kubectl -n kubernetes-dashboard describe secret \
        $(kubectl -n kubernetes-dashboard get secret \
        | grep admin-user | awk '{print $1}')
    

    登錄界面展示

    針對 Chrome 瀏覽器,在空白處點擊然后輸入:thisisunsafe

    針對 Firefox 瀏覽器,遇到證書過期,添加例外訪問

    第二種:授權 dashboard 權限(不適用配置文件)

    • 如果登錄之后提示權限問題的話,可以執行如下操作
    • 把 serviceaccount 綁定在 clusteradmin
    • 授權 serviceaccount 用戶具有整個集群的訪問管理權限
    # 創建serviceaccount
    $ kubectl create serviceaccount dashboard-admin -n kube-system
    # 把serviceaccount綁定在clusteradmin
    # 授權serviceaccount用戶具有整個集群的訪問管理權限
    $ kubectl create clusterrolebinding \
        dashboard-cluster-admin --clusterrole=cluster-admin \
        --serviceaccount=kube-system:dashboard-admin
    # 獲取serviceaccount的secret信息,可得到token令牌的信息
    $ kubectl get secret -n kube-system
    # 通過上邊命令獲取到dashboard-admin-token-slfcr信息
    $ kubectl describe secret admin-token-slfcr> -n kube-system
    # 瀏覽器訪問登錄并把token粘貼進去登錄即可
    https://192.168.30.30:8080/
    # 快捷查看token的命令
    $ kubectl describe secrets -n kube-system \
        $(kubectl -n kube-system get secret | awk '/admin/{print $1}')
    
    kubernetesk8s
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    K8s的主要目標是應對監管大規模容器的復雜性,其通過分布式節點集群管理微服務應用程序,支持擴展、回滾、零停機和自我修復。
    在2021年春季關于Kubernetes安全狀況的報告中,RedHat指出,94%的受訪者在其 Kubernetes環境中遇到過安全事件。這主要是因為在快速采用的同時,K8s仍在不斷發展。托管Kubernetes會將大部分負擔交給托管供應商,并讓組織能夠專注于工作負載而不是基礎設施。這將導致更少的配置錯誤,減少攻擊面。
    近日,云安全公司Aqua發現了一個大規模的加密貨幣挖礦活動,攻擊者利用Kubernetes基于角色的訪問控制來創建后門并運行挖礦惡意軟件。該活動被研究者命名為RBAC Buster,專家指出,這些攻擊正在野外攻擊至少60個集群。攻擊者還會檢查受感染服務器上競爭礦工惡意軟件的證據,并使用RBAC設置來實現持久駐留。專家們發現,自五個月前上傳以來,該Docker鏡像被拉取了14399次。
    對于在共享基礎設施上運行的容器化應用程序來說,安全是至關重要的。隨著越來越多的組織將其容器工作負載轉移到KubernetesK8s已經成為容器協調的首選平臺。而隨著這一趨勢,威脅和新的攻擊方式也越來越多,有必要加強所有的安全層。 在Kubernetes中,安全問題有兩個方面:集群安全和應用安全。我們已經在另一篇文章中介紹了集群安全。在這篇文章中,我們將探討如何確保Kubernetes部署和一般
    零信任策略下K8s安全監控最佳實踐
    Kubebot介紹Kubebot是一款基于Google 云平臺搭建,并且提供了Kubernetes后端的Slackbot安全測試工具。Google云端平臺帳戶。API服務器將請求以消息的形式轉發至PubSub ToolTopic。消息發布至Tool Subscription。Subscription Worker在K8s集群上以Docker容器運行,處理來自Tool Subscription的消息,Worker的數量也可以根據需要進行調整。Tool Worker會將修改信息回傳給Slack,并刪除Tool Worker,因為它們已經完成了自己的任務。Kubebot集成的自動化工作流程列表隨著更多工作流程的添加,此列表將不斷更新wfuzz basic authentication bruteforcingSlack中的Slash命令樣本/runtool nmap|-Pn -p 1-1000|google.com
    從云的虛擬化管理平臺和云網絡構架的一般性知識入手,以 Clos 云網絡架構和 Kubernetes管理平臺為例,俯瞰了當前云計算環境的全貌和細節,宏觀上總覽了云網絡架構和 Kubernetes 管理平臺,微觀上深入連接 fabrics 和容器的細節。
    作為全球數字化轉型的基礎設施,云計算已經在全球范圍得到大規模的應用。企業上云后的 IT 環境變成混合云、多云架構,其網絡暴露面變大,安全管理難度隨之加大,云安全成為各行各業最為關注的焦點之一。與全球相比,中國的云安全市場有共性也有明顯的差異。
    10月28日,美國國家安全局(NSA)和國土安全部網絡安全和基礎設施安全局(CISA)發布《5G云基礎設施安全指南第一編:預防和檢測橫向移動》(Security Guidance for 5G Cloud Infrastructures: Prevent and Detect Lateral Movement),旨在提升5G云基礎設施安全防護能力。
    Clair可以與K8s集成以持續掃描容器鏡像,分析容器映像并提供已知漏洞的報告。Checkov可以集成到CI/CD管道中,以防止部署不安全的設置。Kube-bench可用于驗證K8s的安裝、執行定期檢查并確保符合最佳實踐。它可以與K8s集成以提供流量管理、安全性和可觀察性。
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类