K8S The Hard Way 6/10 - Control Plane
Inicializando o cluster etcd
Os componentes do Kubernetes não têm estado de armazenam, tudo é armazenado no cluster etcd. Neste laboratório, você inicializará um cluster etcd de três nodes e o configurará alta disponibilidade e acesso remoto seguro.
Pré-requisitos
Os comandos neste laboratório devem ser executados em cada controller: controlador-0, controlador-1 e controlador-2. Faça login em cada instância usando o comando vagrant ssh . Exemplo:
vagrant ssh controller-0
Executando comandos em paralelo com tmux
O tmux pode ser usado para executar comandos em várias instâncias de computação ao mesmo tempo. Consulte a seção Executando comandos em paralelo com tmux no laboratório de pré-requisitos.
Provisione o plano de controle do Kubernetes
Crie o diretório de configuração do Kubernetes:
sudo mkdir -p /etc/kubernetes/config
Baixe e instale os binários dos controllers:
Baixe os binários de lançamento oficiais do Kubernetes:
wget -q --show-progress --https-only --timestamping \
"https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-apiserver" \
"https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-controller-manager" \
"https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-scheduler" \
"https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kubectl"
Install the Kubernetes binaries:
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
Configure the Kubernetes API Server
sudo mkdir -p /var/lib/kubernetes/
sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
service-account-key.pem service-account.pem \
encryption-config.yaml /var/lib/kubernetes/
O endereço IP interno da instância será usado para anunciar o API Server aos membros do cluster. Recupere o endereço IP interno da instância de computação atual:
INTERNAL_IP=`echo $SSH_CONNECTION | awk -F " " '{print $3}'`
Create the kube-apiserver.service systemd unit file:
CONTROLLER0=`dig +short controller-0 | grep -v "127.0.1.1" | xargs`
CONTROLLER1=`dig +short controller-1 | grep -v "127.0.1.1" | xargs`
CONTROLLER2=`dig +short controller-2 | grep -v "127.0.1.1" | xargs`
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
--advertise-address=${INTERNAL_IP} \\
--allow-privileged=true \\
--apiserver-count=3 \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/audit.log \\
--authorization-mode=Node,RBAC \\
--bind-address=0.0.0.0 \\
--client-ca-file=/var/lib/kubernetes/ca.pem \\
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--etcd-cafile=/var/lib/kubernetes/ca.pem \\
--etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
--etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
--etcd-servers=https://$CONTROLLER0:2379,https://$CONTROLLER1:2379,https://$CONTROLLER2:2379 \\
--event-ttl=1h \\
--encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
--kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
--kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
--kubelet-https=true \\
--runtime-config='api/all=true' \\
--service-account-key-file=/var/lib/kubernetes/service-account.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--service-node-port-range=30000-32767 \\
--tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
--tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Configure kube-controller-manager
Mova o kube-controller-manager kubeconfig para o diretório:
sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/
Crie o kube-controller-manager.service para o systemd:
cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \\
--bind-address=0.0.0.0 \\
--cluster-cidr=10.200.0.0/16 \\
--cluster-name=kubernetes \\
--cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
--cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
--leader-elect=true \\
--root-ca-file=/var/lib/kubernetes/ca.pem \\
--service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--use-service-account-credentials=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Configure kube-scheduler
Move the kube-scheduler kubeconfig into place:
sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/
Crie o arquivo de configuração kube-scheduler.yaml:
cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
leaderElect: true
EOF
Crie o kube-scheduler.service systemd:
cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
--config=/etc/kubernetes/config/kube-scheduler.yaml \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Inicie os serviços do controlador
sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
Aguarde até 10 segundos para que o servidor da API Kubernetes seja totalmente inicializado.
Habilitar verificações de saúde de HTTP
Um balanceador de carga será usado para distribuir o tráfego entre os três servidores de API e permitir que cada servidor de API encerre as conexões TLS e valide os certificados do cliente. O balanceador de carga de rede só oferece suporte a verificações de integridade HTTP, o que significa que o ponto de extremidade HTTPS exposto pelo servidor de API não pode ser usado. Como solução alternativa, o servidor da web nginx pode ser usado para fazer proxy de verificações de integridade HTTP. Nesta seção, o nginx será instalado e configurado para aceitar verificações de integridade HTTP na porta 80 e fazer proxy das conexões com o servidor API em https://127.0.0.1:6443/healthz.
O ponto de extremidade do servidor da API / healthz não requer autenticação por padrão.
Instale um servidor da web básico para lidar com as verificações de integridade HTTP:
sudo apt-get update
sudo apt-get install -y nginx
cat > kubernetes.default.svc.cluster.local <<EOF
server {
listen 80;
server_name kubernetes.default.svc.cluster.local;
location /healthz {
proxy_pass https://127.0.0.1:6443/healthz;
proxy_ssl_trusted_certificate /var/lib/kubernetes/ca.pem;
}
}
EOF
sudo mv kubernetes.default.svc.cluster.local \
/etc/nginx/sites-available/kubernetes.default.svc.cluster.local
sudo ln -s /etc/nginx/sites-available/kubernetes.default.svc.cluster.local /etc/nginx/sites-enabled/
sudo systemctl restart nginx
sudo systemctl enable nginx
Verificação:
kubectl get componentstatuses --kubeconfig admin.kubeconfig
Saida:
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
Teste o proxy de verificação de integridade HTTP nginx:
curl -H "Host: kubernetes.default.svc.cluster.local" -i http://127.0.0.1/healthz
Saída
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sat, 18 Jul 2020 06:20:48 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Connection: keep-alive
Cache-Control: no-cache, private
X-Content-Type-Options: nosniff
ok
Lembre-se de executar os comandos acima em cada nó do controlador: controlador-0, controlador-1 e controlador-2.
RBAC para autorização Kubelet
Nesta seção, você configurará as permissões RBAC para permitir que o servidor da API Kubernetes acesse a API Kubelet em cada nó de trabalho. O acesso à API Kubelet é necessário para recuperar métricas, registros e executar comandos em pods.
Este tutorial define o sinalizador Kubelet –authorization-mode como Webhook. O modo Webhook usa a API SubjectAccessReview para determinar a autorização.
Os comandos nesta seção afetarão todo o cluster e só precisam ser executados uma vez a partir de um dos nós do controlador.
vagrant ssh controller-0
Crie o sistema: kube-apiserver-to-kubelet ClusterRole com permissões para acessar a API Kubelet e realizar as tarefas mais comuns associadas ao gerenciamento de pods:
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
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
verbs:
- "*"
EOF
O servidor da API do Kubernetes se autentica no Kubelet como o usuário do kubernetes usando o certificado do cliente, conforme definido pela sinalização –kubelet-client-certificate.
Vincule o sistema: kube-apiserver-to-kubelet ClusterRole ao usuário kubernetes:
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
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
Balanceador de carga front-end do Kubernetes
Nesta seção, você provisionará um balanceador de carga externo na frente dos servidores da API Kubernetes. O endereço IP será anexado ao balanceador de carga.
Provisionar um balanceador de carga de rede Crie os recursos de rede do balanceador de carga externo:
vagrant ssh loadbalancer
Instalação do HAProxy:
sudo apt-get update ; sudo apt-get install -y haproxy vim
Editar o arquivo de configuração /etc/haproxy/haproxy.cfg:
CONTROLLER0=`dig +short controller-0 | grep -v "127.0.1.1" | xargs`
CONTROLLER1=`dig +short controller-1 | grep -v "127.0.1.1" | xargs`
CONTROLLER2=`dig +short controller-2 | grep -v "127.0.1.1" | xargs`
cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend proxynode
bind *:80
bind *:6443
stats uri /proxystats
default_backend k8sServers
#<-- Add the following lines to bottom of file
backend k8sServers
balance roundrobin
server controller-0 $CONTROLLER0:6443 check
server controller-1 $CONTROLLER1:6443 check
server controller-2 $CONTROLLER2:6443 check
listen stats
bind :9999
mode http
stats enable
stats hide-version
stats uri /stats
EOF
Inicie o serviço de loadbalance:
sudo systemctl enable haproxy
sudo systemctl start haproxy
Recupere o endereço IP estático do locabalancer:
KUBERNETES_PUBLIC_ADDRESS=`sudo vagrant ssh-config loadbalancer | grep HostName | xargs | sed 's/HostName//g' | xargs`
Faça uma solicitação HTTP para as informações da versão do Kubernetes:
curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version
Saída
{
"major": "1",
"minor": "18",
"gitVersion": "v1.18.6",
"gitCommit": "dff82dc0de47299ab66c83c626e08b245ab19037",
"gitTreeState": "clean",
"buildDate": "2020-07-15T16:51:04Z",
"goVersion": "go1.13.9",
"compiler": "gc",
"platform": "linux/amd64"
}
Proximo: K8S The Hard Way 7/10 - Workers