github.com/cilium/cilium@v1.16.2/Documentation/security/aws.rst (about)

     1  .. only:: not (epub or latex or html)
     2  
     3      WARNING: You are looking at unreleased Cilium documentation.
     4      Please use the official rendered version released here:
     5      https://docs.cilium.io
     6  
     7  .. _aws_metadata_with_policy:
     8  
     9  ***********************************************
    10  Locking Down External Access Using AWS Metadata
    11  ***********************************************
    12  
    13  This document serves as an introduction to using Cilium to enforce policies
    14  based on AWS metadata. It provides a detailed walk-through of running a single-node
    15  Cilium environment on your machine. It is designed to take 15-30 minutes
    16  for users with some experience running Kubernetes.
    17  
    18  
    19  Setup Cilium
    20  ============
    21  
    22  This guide will work with any approach to installing Cilium, including minikube,
    23  as long as the cilium-operator pod in the deployment can reach the AWS API server
    24  However, since the most common use of this mechanism is for Kubernetes clusters
    25  running in AWS, we recommend trying it out along with the guide: :ref:`k8s_install_quick` .
    26  
    27  Create AWS secrets
    28  ==================
    29  
    30  Before installing Cilium, a new Kubernetes Secret with the AWS Tokens needs to
    31  be added to your Kubernetes cluster. This Secret will allow Cilium to gather
    32  information from the AWS API which is needed to implement ToGroups policies.
    33  
    34  AWS Access keys and IAM role
    35  ------------------------------
    36  
    37  To create a new access token the `following guide can be used
    38  <https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html>`_.
    39  These keys need to have certain permissions set:
    40  
    41  .. code-block:: javascript
    42  
    43      {
    44          "Version": "2012-10-17",
    45          "Statement": [
    46              {
    47                  "Effect": "Allow",
    48                  "Action": "ec2:Describe*",
    49                  "Resource": "*"
    50              }
    51          ]
    52      }
    53  
    54  As soon as you have the access tokens, the following secret needs to be added,
    55  with each empty string replaced by the associated value as a base64-encoded string:
    56  
    57  
    58  .. code-block:: yaml
    59      :name: cilium-secret.yaml
    60  
    61      apiVersion: v1
    62      kind: Secret
    63      metadata:
    64        name: cilium-aws
    65        namespace: kube-system
    66      type: Opaque
    67      data:
    68        AWS_ACCESS_KEY_ID: ""
    69        AWS_SECRET_ACCESS_KEY: ""
    70        AWS_DEFAULT_REGION: ""
    71  
    72  The base64 command line utility can be used to generate each value, for example:
    73  
    74  .. code-block:: shell-session
    75  
    76      $ echo -n "eu-west-1"  | base64
    77      ZXUtd2VzdC0x
    78  
    79  This secret stores the AWS credentials, which will be used to connect the AWS
    80  API.
    81  
    82  .. code-block:: shell-session
    83  
    84      $ kubectl create -f cilium-secret.yaml
    85  
    86  To validate that the credentials are correct, the following pod can be created
    87  for debugging purposes:
    88  
    89  .. code-block:: yaml
    90  
    91      apiVersion: v1
    92      kind: Pod
    93      metadata:
    94        name: testing-aws-pod
    95        namespace: kube-system
    96      spec:
    97        containers:
    98        - name: aws-cli
    99          image: mesosphere/aws-cli
   100          command: ['sh', '-c', 'sleep 3600']
   101          env:
   102            - name: AWS_ACCESS_KEY_ID
   103              valueFrom:
   104                secretKeyRef:
   105                  name: cilium-aws
   106                  key: AWS_ACCESS_KEY_ID
   107                  optional: true
   108            - name: AWS_SECRET_ACCESS_KEY
   109              valueFrom:
   110                secretKeyRef:
   111                  name: cilium-aws
   112                  key: AWS_SECRET_ACCESS_KEY
   113                  optional: true
   114            - name: AWS_DEFAULT_REGION
   115              valueFrom:
   116                secretKeyRef:
   117                  name: cilium-aws
   118                  key: AWS_DEFAULT_REGION
   119                  optional: true
   120  
   121  To list all of the available AWS instances, the following command can be used:
   122  
   123  .. code-block:: shell-session
   124  
   125     $ kubectl  -n kube-system exec -ti testing-aws-pod -- aws ec2 describe-instances
   126  
   127  Once the secret has been created and validated, the cilium-operator pod must be
   128  restarted in order to pick up the credentials in the secret.
   129  To do this, identify and delete the existing cilium-operator pod, which will be
   130  recreated automatically:
   131  
   132  .. code-block:: shell-session
   133  
   134      $ kubectl get pods -l name=cilium-operator -n kube-system
   135      NAME                              READY   STATUS    RESTARTS   AGE
   136      cilium-operator-7c9d69f7c-97vqx   1/1     Running   0          36h
   137  
   138      $ kubectl delete pod cilium-operator-7c9d69f7c-97vqx
   139  
   140  
   141  
   142  It is important for this demo that ``coredns`` is working correctly. To know the
   143  status of ``coredns`` you can run the following command:
   144  
   145  .. code-block:: shell-session
   146  
   147      $ kubectl get deployment kube-dns -n kube-system
   148      NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
   149      coredns    2         2         2            2           13h
   150  
   151  Where at least one pod should be available.
   152  
   153  Configure AWS Security Groups
   154  =============================
   155  
   156  Cilium's AWS Metadata filtering capability enables explicit whitelisting
   157  of communication between a subset of pods (identified by Kubernetes labels)
   158  with a set of destination EC2 ENIs (identified by membership in an AWS security group).
   159  
   160  In this example, the destination EC2 elastic network interfaces are attached to
   161  EC2 instances that are members of a single AWS security group ('sg-0f2146100a88d03c3').
   162  Pods with label ``class=xwing`` should only be able to make connections outside the
   163  cluster to the destination network interfaces in that security group.
   164  
   165  To enable this, the VMs acting as Kubernetes worker nodes must be able to
   166  send traffic to the destination VMs that are being accessed by pods.  One approach
   167  for achieving this is to put all Kubernetes worker VMs in a single 'k8s-worker'
   168  security group, and then ensure that any security group that is referenced in a
   169  Cilium toGroups policy has an allow all ingress rule (all ports) for connections from the
   170  'k8s-worker' security group.  Cilium filtering will then ensure that the only pods allowed
   171  by policy can reach the destination VMs.
   172  
   173  Create a sample policy
   174  ======================
   175  
   176  Deploy a demo application:
   177  ----------------------------
   178  
   179  In this case we're going to use a demo application that is used in other guides.
   180  These manifests will create three microservices applications: *deathstar*,
   181  *tiefighter*, and *xwing*. In this case, we are only going to use our *xwing*
   182  microservice to secure communications to existing AWS instances.
   183  
   184  .. parsed-literal::
   185  
   186      $ kubectl create -f \ |SCM_WEB|\/examples/minikube/http-sw-app.yaml
   187      service "deathstar" created
   188      deployment "deathstar" created
   189      deployment "tiefighter" created
   190      deployment "xwing" created
   191  
   192  
   193  Kubernetes will deploy the pods and service in the background. Running ``kubectl
   194  get pods,svc`` will inform you about the progress of the operation.  Each pod
   195  will go through several states until it reaches ``Running`` at which point the
   196  pod is ready.
   197  
   198  .. code-block:: shell-session
   199  
   200      $ kubectl get pods,svc
   201      NAME                             READY     STATUS    RESTARTS   AGE
   202      po/deathstar-76995f4687-2mxb2    1/1       Running   0          1m
   203      po/deathstar-76995f4687-xbgnl    1/1       Running   0          1m
   204      po/tiefighter                    1/1       Running   0          1m
   205      po/xwing                         1/1       Running   0          1m
   206  
   207      NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
   208      svc/deathstar    ClusterIP   10.109.254.198   <none>        80/TCP    3h
   209      svc/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   3h
   210  
   211  Policy Language:
   212  -----------------
   213  
   214  **ToGroups** rules can be used to define policy in relation to cloud providers, like AWS.
   215  
   216  .. code-block:: yaml
   217  
   218      ---
   219      kind: CiliumNetworkPolicy
   220      apiVersion: cilium.io/v2
   221      metadata:
   222        name: to-groups-sample
   223        namespace: default
   224      spec:
   225        endpointSelector:
   226          matchLabels:
   227            org: alliance
   228            class: xwing
   229        egress:
   230        - toPorts:
   231          - ports:
   232            - port: '80'
   233              protocol: TCP
   234          toGroups:
   235          - aws:
   236              securityGroupsIds:
   237              - 'sg-0f2146100a88d03c3'
   238  
   239  This policy allows traffic from pod *xwing* to any AWS elastic network interface
   240  in the security group with ID ``sg-0f2146100a88d03c3``.
   241  
   242  Validate that derived policy is in place
   243  ----------------------------------------
   244  
   245  Every time that a new policy with ToGroups rules is added, an equivalent policy
   246  (also called "derivative policy"), will be created. This policy will contain the
   247  set of CIDRs that correspond to the specification in ToGroups, e.g., the IPs of
   248  all network interfaces that are part of a specified security group. The list of
   249  IPs is updated periodically.
   250  
   251  .. code-block:: shell-session
   252  
   253      $ kubectl get cnp
   254      NAME                                                             AGE
   255      to-groups-sample                                                 11s
   256      to-groups-sample-togroups-044ba7d1-f491-11e8-ad2e-080027d2d952   10s
   257  
   258  Eventually, the derivative policy will contain IPs in the ToCIDR section:
   259  
   260  .. code-block:: shell-session
   261  
   262     $ kubectl get cnp to-groups-sample-togroups-044ba7d1-f491-11e8-ad2e-080027d2d952
   263  
   264  
   265  .. code-block:: yaml
   266  
   267      apiVersion: cilium.io/v2
   268      kind: CiliumNetworkPolicy
   269      metadata:
   270        creationTimestamp: 2018-11-30T11:13:52Z
   271        generation: 1
   272        labels:
   273          io.cilium.network.policy.kind: derivative
   274          io.cilium.network.policy.parent.uuid: 044ba7d1-f491-11e8-ad2e-080027d2d952
   275        name: to-groups-sample-togroups-044ba7d1-f491-11e8-ad2e-080027d2d952
   276        namespace: default
   277        ownerReferences:
   278        - apiVersion: cilium.io/v2
   279          blockOwnerDeletion: true
   280          kind: CiliumNetworkPolicy
   281          name: to-groups-sample
   282          uid: 044ba7d1-f491-11e8-ad2e-080027d2d952
   283        resourceVersion: "34853"
   284        selfLink: /apis/cilium.io/v2/namespaces/default/ciliumnetworkpolicies/to-groups-sample-togroups-044ba7d1-f491-11e8-ad2e-080027d2d952
   285        uid: 04b289ba-f491-11e8-ad2e-080027d2d952
   286      specs:
   287      - egress:
   288        - toCIDRSet:
   289          - cidr: 34.254.113.42/32
   290          - cidr: 172.31.44.160/32
   291          toPorts:
   292          - ports:
   293            - port: "80"
   294              protocol: TCP
   295        endpointSelector:
   296          matchLabels:
   297            any:class: xwing
   298            any:org: alliance
   299            k8s:io.kubernetes.pod.namespace: default
   300        labels:
   301        - key: io.cilium.k8s.policy.name
   302          source: k8s
   303          value: to-groups-sample
   304        - key: io.cilium.k8s.policy.uid
   305          source: k8s
   306          value: 044ba7d1-f491-11e8-ad2e-080027d2d952
   307        - key: io.cilium.k8s.policy.namespace
   308          source: k8s
   309          value: default
   310        - key: io.cilium.k8s.policy.derived-from
   311          source: k8s
   312          value: CiliumNetworkPolicy
   313      status:
   314        nodes:
   315          k8s1:
   316            enforcing: true
   317            lastUpdated: 2018-11-30T11:28:03.907678888Z
   318            localPolicyRevision: 28
   319            ok: true
   320  
   321  The derivative rule should contain the following information:
   322  
   323  - *metadata.OwnerReferences*: that contains the information about the ToGroups
   324    policy.
   325  
   326  - *specs.Egress.ToCIDRSet*:  the list of private and public IPs of the instances
   327    that correspond to the spec of the parent policy.
   328  
   329  - *status*: whether or not the policy is enforced yet, and when the policy was
   330    last updated.
   331  
   332  The endpoint status for the *xwing* should have policy enforcement
   333  enabled only for egress connectivity:
   334  
   335  .. code-block:: shell-session
   336  
   337      $ kubectl exec -q -it -n kube-system cilium-85vtg -- cilium-dbg endpoint get 23453 -o jsonpath='{$[0].status.policy.realized.policy-enabled}'
   338      egress
   339  
   340  In this example, *xwing* pod can only connect to ``34.254.113.42/32`` and
   341  ``172.31.44.160/32`` and connectivity to other IP will be denied.