3
3

More than 1 year has passed since last update.

Centos7サーバーで1からKubernetes環境を構築しIngressでの外部公開・TLSの設定まで行う

Last updated at Posted at 2021-09-19

今回の記事では、Centos7サーバーで1からKubernetes環境を構築し、Ingressでの外部公開・TLSの設定まで行う手順についてまとめていきたいと思います。

今回は、本番環境を試すような設定をしたいと思っているため、CentOS7サーバー1台でマスターノードとワーカーので両方を稼働させるような構築をします。

前提条件

  • CentOS7のサーバー1台が稼働している。
  • Route53にドメインの登録が完了している。

Docker・Kubernetesの初期設定

システムアップデートを行う

# yum update

swapを無効にする

kubeletを正常に動作させるため、SWAPの無効化が必要になる。

# swapoff -a

SWAPの無効を永続化

/etc/fstab
# /dev/mapper/centos-swap swap                    swap    defaults        0 0

Dockerのインストールと起動

# yum install yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce
# mkdir -m 644 /etc/docker
/etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
# systemctl enable docker && systemctl start docker

Kubernetesのインストールと起動

クラスター構築はkubeadmを使用。

/etc/yum.repos.d/kube-rnetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
# yum install kubelet kubeadm --disableexcludes=kubernetes
# systemctl enable kubelet && systemctl start kubelet

Kubernetesに必要なポートを解放

# firewall-cmd --permanent --new-zone=k8s
# firewall-cmd --permanent --zone=k8s --add-port 6443/tcp
# firewall-cmd --permanent --zone=k8s --add-port 2379-2380/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10250/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10251/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10252/tcp
# firewall-cmd --permanent --zone=k8s --add-port 30000-32767/tcp
# firewall-cmd --reload

Kubernetesクラスターの初期構築と設定

バージョン指定が間違っているとエラーが出るので、エラー内容に従って各環境でバージョン指定を行なってください。

# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init  --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.22.2
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config

(Kubernetesクラスターの初期構築と設定に失敗した場合)

エラーなどが出て失敗した場合は、resetしてやり直す。

# kubeadm reset
# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.22.2
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config

flannelをインストールする

コンテナ間通信を行うために必要で、これがないとYAMLファイルを実行してもPod生成が< pending >で止まってしまう。
またコンテナ間通信には、bridgeネットワークcni0の接続を許可するfirewallの設定が必要。

# firewall-cmd --permanent --zone=trusted --change-interface=cni0
# firewall-cmd --reload
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

1台でマスターノードとワーカーノードの両方の役割を持つ設定に変える

デフォルトではマスターノードとワーカーノードは別々のサーバーで動かす前提となっているため、今回の1台のサーバーで両方の役割を持つ設定に変える。

# kubectl taint nodes --all node-role.kubernetes.io/master-

テストでDeploymentのYAMLを実行

deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.17
# kubectl apply -f deploy.yml
# kubectl get pod
NAME                                                           READY   STATUS    RESTARTS         AGE
nginx-deployment-db719865c-nnf24                               1/1     Running   0                17s
nginx-deployment-db744865c-sklvc                               1/1     Running   0                17s

TLSの設定

Route53で設定したドメインについて、Let's EncryptのDNSの認証を行う。
Kubernetes上でTLSの設定を自動化できるcert-managerを使用。

cert-managerのインストール

Kubernetes上でTLS証明書の発行、更新、管理を自動化してくれる。

# kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml

Route53にアクセス権を持つIAMを作成

クラスターからRoute53にリモートアクセスするため、IAMの作成をAWSであらかじめ行う。
公式の設定方法

IAMのシークレットアクセスキーをクラスター内に登録

Secretリソースをroute53-credentials-secretという名前で登録。

# kubectl -n  cert-manager create secret generic route53-credentials-secret --from-literal=secret-access-key=<SECRET_ACCESS_KEY>

ClusterIssuerの作成

証明書を要求するためのClusterIssuer(クラスター全体で使えるIssuer)を作成。
severに関しては一旦テストで実行したのち、問題なければ本番で実行する。

letsencrypte-issuer.yml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-issuer
spec:
  acme:
    # server: https://acme-v02.api.letsencrypt.org/directory #本番
    server: https://acme-staging-v02.api.letsencrypt.org/directory #テスト
    email: <Mail_Address>
    privateKeySecretRef:
      name: letsencrypt-issuer
    solvers:
      - selector:
          dnsZones:
          - "test.com" #Route53で設定しているドメイン名
        dns01:
          route53:
            region: ap-northeast-1
            accessKeyID: <ACCESS_KEY>
            secretAccessKeySecretRef:
              name: route53-credentials-secret #登録したSecretリソース
              key: secret-access-key
# kubectl apply -f letsencrypte-issuer.yml
# kubectl describe clusterissuer
Status:
  Acme:
    Last Registered Email:  <Mail_Address>
    Uri:                    https://acme-v02.api.letsencrypt.org/acme/acct/xxxxxxxx
  Conditions:
    Last Transition Time:  2021-09-21T05:28:09Z
    Message:               The ACME account was registered with the ACME server
    Reason:                ACMEAccountRegistered
    Status:                True
    Type:                  Ready
Events:                    <none>

Certificateの作成

証明書の作成を行う。

certificate.yml
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: test-com
spec:
  secretName: test-com-tls
  duration: 2160h
  renewBefore: 360h
  organization:
  - test
  commonName: "*.test.com"
  isCA: false
  keySize: 2048
  keyAlgorithm: rsa
  keyEncoding: pkcs1
  usages:
    - server auth
    - client auth
  dnsNames:
  - test.com
  - "*.test.com"
  issuerRef:
    name: letsencrypt-issuer
    kind: ClusterIssuer
# kubectl apply -f certificate.yml

しばらく経ったのち、成功すればtest-com-tlsが作成される。

# kubectl describe certificate -A
---
 Normal  Issued        30m   cert-manager  Certificate issued successfully
---
# kubectl describe secret test-com-tls

Ingressの設定

設定したTLSとIngressリソースを使って、ドメイン名でTLSの外部公開を行う。

Nginx Ingress Controllerをインストール

Ingressを外部公開して使うためには、Nginx Ingress Controllerのインストールが必要。

# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml

今回は外部のロードバランサーなどを使用しないため、以下を編集し追記する。

# kubectl edit service ingress-nginx-controller -n ingress-nginx
---
  type: LoadBalancer
  externalIPs:
  - <SERVER_IP> #自身のサーバーのIPアドレス
---

テストでNGINXのトップページを表示

Deploymentに関しては、上記で記載したdeployment.ymlを使用。

service.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  ports:
    - port: 80
  selector:
    app: nginx
ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/tls-acme: "true"
    ingress.kubernetes.io/ssl-redirect: "false"
    cert-manager.io/cluster-issuer: "letsencrypt-issuer"
spec:
  tls:
  - hosts:
      - example.test.com #Route53で登録したAレコードのドメイン名
    secretName: test-com-tls
  rules:
    - host: example.test.com #Route53で登録したAレコードのドメイン名
      http:
        paths:
          - backend:
              service:
                name: nginx-service
                port:
                  number: 80
            path: /
            pathType: Prefix

Hostで記載したURLのhttpsにアクセスし、Nginxのトップページがひらけば成功。

demo

参考にさせていただいた記事のURL

https://qiita.com/shikigamix/items/3f3078cb4c9883554689
https://qiita.com/zembutsu/items/399774c5071050f07975
https://qiita.com/jlandowner/items/9f3c4c0a03d2ae3d2189
https://qiita.com/iqustechtips/items/1ec6b32a98b3fab427d6

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3